views:

742

answers:

4

Hello

I have a exported function in a c++ DLL

// C++ DLL (Blarggg.dll)

extern "C"
{
     USHORT ReadProperty( BYTE * messsage, USHORT length, BYTE * invokeID ) 
    {
         if( invokeID != NULL ) {
            * invokeID = 10 ; 
        }
         return 0;
    }
}

That I would like to make it available to my C# application

// C# app 
[DllImport("Blarggg.dll")]
public static extern System.UInt16 ReadProperty(
        /* [OUT] */ System.Byte[] message,
        /* [IN]  */ System.UInt16 length,
        /* [OUT] */ System.Byte[] invokeID ); 


private void DoIt() 
{
    System.Byte[] message = new System.Byte[2000];
    System.Byte[] InvokeID = new System.Byte[1];
    System.UInt16 ret = ReadProperty( message, 2000, InvokeID ); // Error 
}

The problem is that I keep getting the following error message.

An unhanded exception of type 'System.NullReferenceException' occurred in Blarggg.dll Additional information: Object reference not set to an instance of an object.

I'm using VS2008 to build both the DLL and the C# application.

I'm not a C# programmer.

What am I doing wrong?

A: 

You might need to use the System.Runtime.InteropServices.Marshal class to convert between managed and unmanaged types.

John K
A: 

Can you do this with C++ types?

I was under the impression that you could only DLLImport C dlls.

We use DLLImport with C++ Dll's just fine but we declare our external functions as

extern "C" __declspec(dllexport) ...

Have a look at this web page:

http://dotnetperls.com/dllimport-interop

chollida
I should have mentioned that (BYTE = unsigned char, USHORT = unsigned short) both are C data type.
Steven smethurst
I added the extern "C" to the question, it is in my original code but it does help with this problem.
Steven smethurst
You can definitely DLLImport C++ dll's, the 'extern C' is solely to avoid name mangling, and you can accomplish the same thing in another way.
Ed Swangren
did you also declare the C++ function as __declspec(dllexport) ?
asveikau
+2  A: 

I pasted your code directly into VS2008 and it runs perfectly on my 32-bit machine (added a .def file to set the exported name). Is your C++ library definitely a pure win32 project? The error message you gave seems to imply that it threw a CLR exception.

Dave Cluderay
I copied the code from my currently project in to a new project and I was able to compile and run it with out any problems. It must have something to do with the project or anther part of my application. thank you.
Steven smethurst
+2  A: 

Try this:

[DllImport("Blarggg.dll", CallingConvention := CallingConvention.Cdecl)] 
public static extern System.UInt16 ReadProperty( 
        /* [IN]  */ System.Byte[] message, 
        /* [IN]  */ System.UInt16 length, 
        /* [OUT] */ out System.Byte invokeID );  


private void DoIt()  
{ 
    System.Byte[] message = new System.Byte[2000]; 
    System.Byte InvokeID; 
    System.UInt16 ret = ReadProperty( message, 2000, out InvokeID );
}
Remy Lebeau - TeamB