简体   繁体   中英

C#: How to receive a double pointer to struct from a C++ unmanaged function callback

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 etc? I tried fS + Marshal.SizeOf(typeof(IplImage)) with no luck... any ideas?

No ideas at all?

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM