P/Invoke Marshalling an Out void*
本文关键字:Out void an Marshalling Invoke | 更新日期: 2023-09-27 17:58:12
我有以下C函数定义:
EXPORT CreateWindow(const wchar_t* applicationTitle, void* windowHandle) {
// Some preconditions & other stuff here
windowHandle = RENDER_COMPONENT.Window.CreateNew(cstr_to_wstring(applicationTitle));
return true;
}
该函数是通过p/Invoke调用的。P/Invoke函数定义如下:
[DllImport(InteropUtils.RUNTIME_DLL, EntryPoint = "CreateWindow", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool _CreateWindow([MarshalAs(UnmanagedType.LPWStr)] string applicationTitle, [Out] out IntPtr windowHandle);
此功能的用途是:
IntPtr windowHandle;
bool windowCreationSuccess = _CreateWindow(Engine.ApplicationTitle, out windowHandle);
我的问题是,在C#代码中,windowHandle
总是等于IntPtr.Zero,我想这意味着它没有以某种方式从C++"复制"到C#端。它是在C函数中设置的(我用调试器查看过)——它实际上是一个HWND。
p/Invoke从未停止让我感到困惑——我确信我在复制结构而不是引用它或其他东西时做错了什么,但我不太清楚是什么/在哪里。
C仅使用传递值。这意味着您对windowHandle
的分配永远不会被调用者看到。这对任何打电话的人来说都是如此,而不仅仅是一个有管理的pinvoke。
您需要更改C函数以接收窗口句柄变量的地址。像这样:
EXPORT CreateWindow(const wchar_t* applicationTitle, HWND* windowHandle) {
// Some preconditions & other stuff here
*windowHandle = RENDER_COMPONENT.Window.CreateNew(cstr_to_wstring(applicationTitle));
return true;
}
然后问题中的C#代码匹配。
然而,您的C代码很奇怪。你为什么无条件地返回真?如果总是真的,为什么还要麻烦回一个bool呢。坦率地说,归还HWND会更干净。