Search code examples
c#dlloculus

Passing a char* argument to a C++ DLL function from a C# app


I am trying to use a dll function declared as void Process(char* data) from C#.

The dll provides various functions to operate an OculusRift. This function is supposed to display in the Oculus the data image and it is used by another fully functioning app.

In my code, I generate a byte[] from a Bitmap image, then I convert it into other things (char[], append a StringBuilder,...) aiming at passing this to the Process function.

I load this process function from a DLL via LoadLibrary (to load the DLL) + GetProcAdress (to access the function). I can't use DLLImport because I want to be as close as possible to the way the interface of the other app (written in C++) works with the DLL.

I tried using
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void Process([MarshalAs(UnmanagedType.LPStr)]StringBuilder data);

or simply
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void Process(StringBuilder data);

(I read passing a string/StringBuilder could do the trick because it's marshaled by default as a char*). As a result I had the full string passed as an argument to the DLL and not a char*.

I tried to pass an IntPtr as argument too, using Marshal Copy and

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void Process(IntPtr data);.
As a result I had a Memory Access Violation Exception.

I then tried various things using unsafe code such as implementing the whole data creation process from the other app (for my purposes I only need a simplified version) or creating the data as I want in a char[] and then copying this char[] to a char* which I passed to

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] private unsafe delegate void Process(char* data);

This resulted in stack overflow exceptions from stackalloc and in Memory Access Violation Exception.

At this point, I think I'm missing something and need your help. I don't know if there is some kind of lock causing the Memory Exception Error (I made sure the image is of the right size), I don't know if I've not fully misunderstood the marshaling process, etc.

I hope I've been explicit enough concerning my problem.


Solution

  • In C char is used to represent bytes because in C the type byte doesn't exists. Or is just equal to the char type.

    So to map from C#:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    private delegate void Process([MarshalAs(UnmanagedType.LPArray)]byte[] data);
    

    or

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    private delegate void Process(byte[] data);
    

    Regards