簡體   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. 我認為這是因為 C# 庫中的 GC 在 C++ 項目中不起作用,我不知道如何解決。 請幫我。

我的代碼如下:

  1. 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++

    #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. 執行人
    #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);
        }
    }

來自SafeArrayAccessData 文檔

調用 SafeArrayAccessData 后,必須調用 SafeArrayUnaccessData function 才能解鎖陣列。

不確定這是泄漏的實際原因。 但是在調試問題時,一個好的第一步是確保您遵循文檔中指定的所有規則。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM