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 = CallingCon开发者_如何转开发vention.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?
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.
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.
精彩评论