在 C# 中保留 C++ 指针
Preserve C++ Pointer in C#
我正在用 C# 编写一个小程序,其中包含一个 C++ Dll。
在 C++ 中,有许多 classes 需要实例化以备后用。
这看起来像以下函数:
C++:
__declspec(dllexport) FrameCapture* GetFrameCapturer(HWND windowHandle) {
ProcessWindow* window = ProcessWindowCollection::GetInstance()->FindWindow(windowHandle);
FrameCapture* capture = new FrameCapture(window);
return capture;
}
如您所见,我只是创建了一个 FrameCapture class 和 return 一个指向它的指针。
此指针作为 IntPtr 存储在 C# 中。
C#:
[DllImport("<dllnamehere>")]
public static extern IntPtr GetFrameCapturer(IntPtr windowHandle);
目前为止效果很好。
但是,如果我使用该指针获取 FrameCapture
的实例
C++:
__declspec(dllexport) BITMAPFILEHEADER* GetBitmapFileHeader(FrameCapture* frameCapturer) {
return frameCapturer->GetBitmapFileHeader();
}
class 将完全为空。
如何获取我在第一步中初始化的 Class 的实例?
编辑:
我做了一些测试,并将指针替换为更好看的整数。
我将 'capture' 转换为 Int32,然后 return 编辑了它。
在我的测试用例中,它 returned byte(208,113,244,194)。
正如预期的那样,此值在 C++ 和 C# 中是相同的。
但是,现在变得奇怪了。
如果我将这个 Int32 传递给 'GetBitmapFileHeader' 值突然变成 byte(184,231,223,55).
那还差得远呢!我想到了 Little <-> Big Endian 或类似的东西,但是,这是一个全新的 Memoryblock?
IntPtr 也会出现同样的行为。
根据要求,我 post 还导入了 'GetBitmapFileHeader'
[DllImport("<dllnamehere>")]
public static extern tagBITMAPFILEHEADER GetBitmapFileHeader(IntPtr capturerHandle);
好的,我知道了。
查看此从 C# 导入。
C#:
[DllImport("<dllnamehere>")]
public static extern tagBITMAPFILEHEADER GetBitmapFileHeader(IntPtr capturerHandle);
错了!
函数现在 returns IntPtr 完全可以正常工作。
这是新的设置:
C++:
__declspec(dllexport) void* __stdcall GetBitmapFileHeader(void* frameCapturer) {
FrameCapture* cap = (FrameCapture*)frameCapturer;
return cap->GetBitmapFileHeader();
}
C#:
[DllImport("libWinCap.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetBitmapFileHeader(IntPtr frameCapturer);
[...]
//calling
IntPtr ptr = GetBitmapFileHeader(m_capturerHandle);
m_bitmap.m_fileHeader = (tagBITMAPFILEHEADER)Marshal.PtrToStructure(ptr, typeof(tagBITMAPFILEHEADER));
我现在只移动指针并使用 PtrToStructure 读取内存。
此外,感谢您的每一条评论。
我正在用 C# 编写一个小程序,其中包含一个 C++ Dll。
在 C++ 中,有许多 classes 需要实例化以备后用。 这看起来像以下函数:
C++:
__declspec(dllexport) FrameCapture* GetFrameCapturer(HWND windowHandle) {
ProcessWindow* window = ProcessWindowCollection::GetInstance()->FindWindow(windowHandle);
FrameCapture* capture = new FrameCapture(window);
return capture;
}
如您所见,我只是创建了一个 FrameCapture class 和 return 一个指向它的指针。
此指针作为 IntPtr 存储在 C# 中。
C#:
[DllImport("<dllnamehere>")]
public static extern IntPtr GetFrameCapturer(IntPtr windowHandle);
目前为止效果很好。 但是,如果我使用该指针获取 FrameCapture
的实例C++:
__declspec(dllexport) BITMAPFILEHEADER* GetBitmapFileHeader(FrameCapture* frameCapturer) {
return frameCapturer->GetBitmapFileHeader();
}
class 将完全为空。 如何获取我在第一步中初始化的 Class 的实例?
编辑:
我做了一些测试,并将指针替换为更好看的整数。
我将 'capture' 转换为 Int32,然后 return 编辑了它。 在我的测试用例中,它 returned byte(208,113,244,194)。 正如预期的那样,此值在 C++ 和 C# 中是相同的。
但是,现在变得奇怪了。
如果我将这个 Int32 传递给 'GetBitmapFileHeader' 值突然变成 byte(184,231,223,55).
那还差得远呢!我想到了 Little <-> Big Endian 或类似的东西,但是,这是一个全新的 Memoryblock?
IntPtr 也会出现同样的行为。
根据要求,我 post 还导入了 'GetBitmapFileHeader'
[DllImport("<dllnamehere>")]
public static extern tagBITMAPFILEHEADER GetBitmapFileHeader(IntPtr capturerHandle);
好的,我知道了。
查看此从 C# 导入。
C#:
[DllImport("<dllnamehere>")]
public static extern tagBITMAPFILEHEADER GetBitmapFileHeader(IntPtr capturerHandle);
错了!
函数现在 returns IntPtr 完全可以正常工作。
这是新的设置:
C++:
__declspec(dllexport) void* __stdcall GetBitmapFileHeader(void* frameCapturer) {
FrameCapture* cap = (FrameCapture*)frameCapturer;
return cap->GetBitmapFileHeader();
}
C#:
[DllImport("libWinCap.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetBitmapFileHeader(IntPtr frameCapturer);
[...]
//calling
IntPtr ptr = GetBitmapFileHeader(m_capturerHandle);
m_bitmap.m_fileHeader = (tagBITMAPFILEHEADER)Marshal.PtrToStructure(ptr, typeof(tagBITMAPFILEHEADER));
我现在只移动指针并使用 PtrToStructure 读取内存。
此外,感谢您的每一条评论。