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从未停止让我感到困惑——我确信我在复制结构而不是引用它或其他东西时做错了什么,但我不太清楚是什么/在哪里。

P/Invoke Marshalling an Out void*

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会更干净。