• Advertisement
Sign in to follow this  

[.net] Help with using C++ Dll in C#

This topic is 4168 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have the following code in a C++ Dll.

_declspec(dllexport) struct myStruct
	{
		int a;
		char name[20];
	};

	_declspec(dllexport) void Modify(myStruct *o)
	{
		o[0].a = 5;
		strcpy(o[0].name, "Sean");

	}


I load the functions in C# like this:
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 2)]
        public struct myStruct
	    {
            [MarshalAs(UnmanagedType.I4)]
            public int a;
            [MarshalAs(UnmanagedType.LPStr)]
            public string name;
	    };

        [DllImport("C++ Dll.dll")]
        public static extern void Modify(IntPtr o);


Now what I would like to do, is in C#, declare an instance of myStruct, pass it into Modify and then print out the results.  I do it like this:


static void Main(string[] args) {

      myStruct obj = new myStruct();
      IntPtr target = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
      Modify(target);

      Marshal.PtrToStructure(target, obj);
}

But I get the following exception: Unhandled Exception: System.ArgumentException: The structure must not be a value class. Parameter name: structure at System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr ptr, Ob ject structure, Boolean allowValueClasses) at System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr, Object s tructure) at UsbHidApiCSharp.Program.Main(String[] args) in C:\Projects\UsbHidApiCSharp \UsbHidApiCSharp\Program.cs:line 86 Anybody have any ideas why or a different way I can accomplish this?

Share this post


Link to post
Share on other sites
Advertisement
I'm not saying you can't do what you want to do, but the much more common method of creating mixed native and .NET programs is to write the .NET wrapper layer in managed C++, not C#. So in your case there would be 3 pieces, the native c++ objects, the managed c++ wrapper objects, and the c# client code. Writing the wrapper objects in C# just creates too much potential confusion because of keyword differences everywhere in the system (string, int, struct, ...). The only level of C++ wrapping I do directly in C# is wrapping stand-alone (C) functions, such as OpenGL or Win32 API functions.

Good Luck.

Share this post


Link to post
Share on other sites
The exception message is quite clear. PtrToStructure(IntPtr, Object) does not accept value types. Use PtrToStructure(IntPtr, Type). Or you could just rewrite your decleration a bit to be:

public static extern void Modify(ref myStruct o);

Share this post


Link to post
Share on other sites
Quote:
Original post by Washu
The exception message is quite clear. PtrToStructure(IntPtr, Object) does not accept value types. Use PtrToStructure(IntPtr, Type). Or you could just rewrite your decleration a bit to be:

public static extern void Modify(ref myStruct o);


I tried that and it worked perfect, Thanks! But now I have another problem. What if I have a function in my C++ DLL that creates a myStruct object and then returns it like this:


myStruct *GetMyStruct()
{
myStruct obj = new myStruct;
return myStruct;
}



I define it in C# and call it like this:

[DllImport("C++ Dll.dll")]
public static extern myStruct GetMyStruct();

myStruct obj = GetMyStruct();



But it throws the following exception:

Unhandled Exception: System.Runtime.InteropServices.MarshalDirectiveException: M
ethod's type signature is not PInvoke compatible.
at UsbHidApiCSharp.Program.GetMyStruct()
at UsbHidApiCSharp.Program.Main(String[] args) in C:\Projects\UsbHidApiCSharp
\UsbHidApiCSharp\Program.cs:line 87

Share this post


Link to post
Share on other sites
That method does not return a value type of the type myStruct but an IntPtr. So you will need to use Marshal.PtrToStructure in that case, and a return type of IntPtr.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement