C#:如何从 C++ 接收结构的双指针非托管函数回调
我会简洁的。 我有一个使用 openCV lib 用 C++ 编写的库。 我的功能之一是:
EXTERN_HEADER HWND createHandle(FListener fl);
其中 FListener 是一个回调函数指针,定义为:
typedef void (__stdcall *FListener)
(int fSN, int fC, byte* fSData, IplImage **fS);
IplImage 是一个 openCV 结构。
我正在尝试在 C# 中使用这个库和这些函数,所以我这样进行 DllImport-ing:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void FListener(int fSN, int fC, ref byte fSData, ref IntPtr fS);
[DllImport("FLib.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.Cdecl)]
static extern int createHandle(FListener fl);
最后我声明将回调到我的 C# 程序的方法为:
private void test(int fSN, int fC, ref byte fSD, ref IntPtr fS)
{
//how -for the love of God- do I access that openCV double pointer struct
//inside "fS"?
}
当然 fS 是一个指向指向的指针数组的指针IplImages。 我是否必须在 C# 代码中再次声明 IplImage 结构? 我不想为 openCV 使用任何 C# 包装器。我想让事情保持“干净”和“简单” 但我完全被编组部分困住了......任何帮助将不胜感激。
更新:如果我将 fS 数组作为 IntPtr* 传递,它就像一个魅力。这些元素以 fS[0]、fS[1] 等形式检索。如果我将其作为“ref IntPtr”传递,那么第一个元素可以作为 fS 检索,但我在哪里可以找到第二个元素等?我尝试了 fS + Marshal.SizeOf(typeof(IplImage)) 但没有运气......有什么想法吗?
完全没有想法吗?
I will be laconic.
I have a library written in C++ using the openCV lib.
One of my functions is:
EXTERN_HEADER HWND createHandle(FListener fl);
where FListener is a callback function pointer defined as:
typedef void (__stdcall *FListener)
(int fSN, int fC, byte* fSData, IplImage **fS);
IplImage is an openCV struct.
I am trying to use this library and these functions in C# so i am DllImport-ing as such:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void FListener(int fSN, int fC, ref byte fSData, ref IntPtr fS);
[DllImport("FLib.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.Cdecl)]
static extern int createHandle(FListener fl);
and finally i declare the method that will be called back to my c# program as:
private void test(int fSN, int fC, ref byte fSD, ref IntPtr fS)
{
//how -for the love of God- do I access that openCV double pointer struct
//inside "fS"?
}
Naturally fS is a pointer to an array of pointers pointing to IplImages.
Do I have to declare the IplImage struct again inside my C# code?
I dont want to use any C# wrapper for openCV. I want to keep things "clean" and "simple"
but i am totally stuck with the marshalling part... Any help would be appreciated.
UPDATE: If i pass the fS array as an IntPtr* it works like a charm. The elements are retrieved as fS[0], fS[1] etc. If I pass it as a "ref IntPtr" then the first element can be retrieved as fS but where can i find the second one e.t.c.? I tried fS + Marshal.SizeOf(typeof(IplImage)) with no luck... any ideas?
No ideas at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
自从我完成 Platform Invoke 以来已经有一段时间了,但我认为您的回调必须是不安全的,例如,
这可能不是确切的语法,但它应该让您朝着正确的方向前进。
It's been a while since I've done Platform Invoke, but I think your callback will have to be unsafe, e.g.,
This may not be the exact syntax, but it should get you going in the right direction.
至于你的第二个问题,你可以使用不安全代码中的 IntPtr.ToPointer() 方法访问其他元素,这样你将有一个指向结构体/指针数组或其他内容的基础的指针,然后你可以简单地使用索引器访问它们,例如:
如果它是指向 IntPtrs 数组的指针,则执行相同操作,再次使用 ToPointer。
As for your second question, you can access the other elements using the IntPtr.ToPointer() method in unsafe code, so that you will have a pointer to the base of the structure/array of pointers or whatever, and then you can simply use the indexer the access them, for example:
if it's a pointer to array of IntPtrs do the same, ToPointer once again.