包装C对象以便与C#PInvoke一起使用时的析构函数执行
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了包装C对象以便与C#PInvoke一起使用时的析构函数执行,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2100字,纯文字阅读大概需要4分钟。
内容图文
![包装C对象以便与C#PInvoke一起使用时的析构函数执行](/upload/InfoBanner/zyjiaocheng/800/9ccc1aa785474dd3a918590adb3ff6cb.jpg)
我有一个C类,我想在C#中使用.为此,我试图编写另一个C dll来包装这个类(它是另一个库的一部分),具有可调用的函数(使用“extern C和__declspec(dllexport)”).
我的想法是保持指向我的对象的指针并将其发送到包装器DLL中的函数,然后从那里调用该对象的方法.这看起来很好但是当对象具有解构器时会出现问题.
这是我的C包装器代码:( Device是我的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的生命周期.然后删除dl;在Device_Close()函数中.
请注意,C函数将地址分配给函数本地的Device *,调用者不会看到它.要解决这个问题,在C端,您可以通过引用传递指针:
__declspec(dllexport) Status Device_open(Device*& di, const char* uri)
或者你可以通过设备**.
__declspec(dllexport) Status Device_open(Device** di, const char* uri)
但是,我不确定这会对c#方面产生什么影响.
为防止任何内存泄漏,请确保在调用dl.open(url)失败时删除新的Device实例:
__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#PInvoke一起使用时的析构函数执行全部内容,希望文章能够帮你解决包装C对象以便与C#PInvoke一起使用时的析构函数执行所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。