简体   繁体   English

Memory 在 ZF6F87C9FDCF8B3C3F07F93F1EE8712 中使用 C# dll 时泄漏

[英]Memory leak while using C# dll in a C++

The situation is, I wrapped C# dll to use it in a C++ project and when I execute C++ project I can't see any sign about memory leak but the memory increases little by little. The situation is, I wrapped C# dll to use it in a C++ project and when I execute C++ project I can't see any sign about memory leak but the memory increases little by little. I think it's because the GC in C# library doesn't work in C++ project and I don't know how to solve it.我认为这是因为 C# 库中的 GC 在 C++ 项目中不起作用,我不知道如何解决。 Please help me.请帮我。

My code is below:我的代码如下:

  1. C# C#
    using Microsoft.Win32.SafeHandles;
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    namespace CSharpLib
    {

        [Guid("8EA9EAA8-CA3D-4584-B1E0-7B9561757CA4")]
        public interface ICSharpLibrary
        {
            int[] GetData();
            string GetName();
            bool Init();
        }

        [Guid("B62A2B51-621D-41AA-8F4F-021E404B593C")]
        public class CSharpLibrary : ICSharpLibrary, IDisposable
        {
            private bool disposed = false;

            private int[] data;

            private string name = "CSharpLib";

            private SafeHandle safeHandle = new SafeFileHandle(IntPtr.Zero, true);

            private void MakeData()
            {
                var list = new List<int>();
                var rnd = new Random();
                for(var i = 0; i < 1000; i++)
                {
                    list.Add(rnd.Next(0, 255));
                }
    
                data = list.ToArray();
            }
    
            public int[] GetData()
            {
                MakeData();
                return data;
            }
    
            public string GetName()
            {
                return name;
            }
    
            public bool Init()
            {
                data = null;
    
                return true;
            }
    
            public void Dispose()
            {
                Dispose(true);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposed)
                {
                    return;
                }
                if (disposing)
                {
                    data = null;
                    safeHandle.Dispose();
                }
    
                disposed = true;
            }
        }
    }
  1. C++ C++

    #pragma once
    
    #ifdef CPLUSLIBRARY_EXPORTS
    #define CPLUSLIBRARY_API __declspec(dllexport)
    #else
    #define CPLUSLIBRARY_API __declspec(dllimport)
    #endif
    
    extern "C" CPLUSLIBRARY_API bool Init();
    
    extern "C" CPLUSLIBRARY_API int* GetData();
    
    extern "C" CPLUSLIBRARY_API char* GetName();

    #include <Windows.h>
    #include "pch.h"
    #include "CPlusLibrary.h"
    
    #import "lib/CSharpLibrary.tlb" no_namespace named_guids
    
    ICSharpLibrary* lib = NULL;
    int* data = NULL;
    bool isWorking = false;
    char* name = NULL;
    
    bool Init() {
        HRESULT hr = CoInitializeEx(NULL, tagCOINIT::COINIT_MULTITHREADED);
    
        if (!SUCCEEDED(hr))
            return false;
    
        hr = CoCreateInstance(CLSID_CSharpLibrary, NULL, CLSCTX_INPROC_SERVER, IID_ICSharpLibrary, reinterpret_cast<void**>(&lib));
    
        if (!SUCCEEDED(hr))
            return false;
    
        return true;
    }
    
    int* GetData() {
        auto raw = lib->GetData();
        void* pVoid = NULL;
    
        HRESULT hr = ::SafeArrayAccessData(raw, &pVoid);
    
        if (!SUCCEEDED(hr))
            return NULL;
        auto result = reinterpret_cast<int*>(pVoid);
    
        return result;
    }
    
    char* GetName() {
        char str[10];
        strcpy_s(str, lib->GetName());
        name = str;
    
        return name;
    }
  1. executor执行人
    #include <iostream>
    #include <CPlusLibrary.h>
    #include <CoreWindow.h>
    
    int main()
    {
        if (!Init())
            return 0;
    
        while (true) {
            auto name = GetName();
            std::cout << name << std::endl;
            auto data = GetData();
    
            for (int i = 0; i < 1000; i++) {
                std::cout << data[i];
            }
    
            std::cout << std::endl;
    
            Sleep(100);
        }
    }

From SafeArrayAccessData documentation来自SafeArrayAccessData 文档

After calling SafeArrayAccessData, you must call the SafeArrayUnaccessData function to unlock the array.调用 SafeArrayAccessData 后,必须调用 SafeArrayUnaccessData function 才能解锁阵列。

Not sure this is the actual reason for the leak.不确定这是泄漏的实际原因。 But when debugging problems, a good first step is to ensure you are following all the rules specified in the documentation.但是在调试问题时,一个好的第一步是确保您遵循文档中指定的所有规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM