gpt4 book ai didi

c# - 包装 C++ 对象以用于 C# PInvoke 时的析构函数执行

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:46:33 25 4
gpt4 key购买 nike

我有一个要在 C# 中使用的 C++ 类。为此,我试图编写另一个 C++ dll 来用可调用函数(使用“extern C 和 __declspec(dllexport)”)包装此类(它是另一个库的一部分)。我的想法是保留一个指向我的对象的指针并将其发送到包装器 dll 中的函数,然后从那里调用该对象的方法。这看起来不错,但当对象具有解构函数时就会出现问题。

这是我的 C++ 包装器代码:(设备是我的 C++ 类/对象)

__declspec(dllexport) Status Device_open(Device* di, const char* uri)
{
Device dl;
Status status = dl.open(uri);
di = &dl;
return status;
}
__declspec(dllexport) void Device_Close(Device* di)
{
di->close();
}

这是我的 C# 包装器代码:

    [DllImport("Wrapper.dll")]
static extern Status Device_open(ref IntPtr objectHandler, IntPtr uri);
public static Device Open(string uri)
{
IntPtr handle = IntPtr.Zero;
Device_open(ref handle, Marshal.StringToHGlobalAnsi(uri));
return new Device(handle);
}
[DllImport("Wrapper.dll")]
static extern void Device_Close(IntPtr objectHandler);
public void Close()
{
Device_Close(this.Handle);
}

这是 C# 应用程序中的测试代码:

    Device d = Device.Open(di.URI);
d.Close();

一切都很好。问题在于,当我请求打开一个新设备时,主 C++ 对象的解构函数将被执行,所以我的关闭请求总是返回异常(因为它已经关闭或被破坏);

我能做些什么来防止这种情况发生?!

最佳答案

Device 正在被破坏,因为它超出了 Device_open() 函数末尾的范围。要解决这个问题,请使用 new 动态分配 Device 实例,这样您就可以控制 dl 的生命周期。然后在 Device_Close() 函数中 delete dl;

请注意,C++ 函数正在将地址分配给函数本地的 Device*,调用者看不到它。要解决此问题,在 C++ 端,您可以通过引用传递指针:

__declspec(dllexport) Status Device_open(Device*& di, const char* uri)

或者您可以传递一个Device**

__declspec(dllexport) Status Device_open(Device** di, const char* uri)

但是,我不确定这将如何影响 C# 端。

为防止任何内存泄漏,如果调用 dl.open( url) 失败:

__declspec(dllexport) Status Device_open(Device*& di, const char* uri)
{
Status status;
try
{
Device* dl = new Device();
status = dl->open(uri);
if (status != OK)
{
delete dl;
}
else
{
di = dl;
}
}
catch (std::bad_alloc const&)
{
status = BAD_ALLOC; // Or equivalent failure reason.
}
return status;
}

__declspec(dllexport) void Device_Close(Device* di)
{
// di->close(); Uncomment if destructor does not close().
delete di;
}

关于c# - 包装 C++ 对象以用于 C# PInvoke 时的析构函数执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14817178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com