C#:如何从 C++ 接收结构的双指针非托管函数回调

发布于 2024-10-07 23:38:59 字数 1218 浏览 6 评论 0原文

我会简洁的。 我有一个使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不知所踪 2024-10-14 23:38:59

自从我完成 Platform Invoke 以来已经有一段时间了,但我认为您的回调必须是不安全的,例如,

unsafe delegate void FListener(int fSN, int fC, ref byte fSData, IplImage **fS);

这可能不是确切的语法,但它应该让您朝着正确的方向前进。

It's been a while since I've done Platform Invoke, but I think your callback will have to be unsafe, e.g.,

unsafe delegate void FListener(int fSN, int fC, ref byte fSData, IplImage **fS);

This may not be the exact syntax, but it should get you going in the right direction.

腻橙味 2024-10-14 23:38:59

至于你的第二个问题,你可以使用不安全代码中的 IntPtr.ToPointer() 方法访问其他元素,这样你将有一个指向结构体/指针数组或其他内容的基础的指针,然后你可以简单地使用索引器访问它们,例如:

int* p = (int*)fS.ToPointer();
p[3] = ...;

如果它是指向 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:

int* p = (int*)fS.ToPointer();
p[3] = ...;

if it's a pointer to array of IntPtrs do the same, ToPointer once again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文