poco
poco

Reputation: 3005

C# dll import function correctly

I am trying to import a function from a c dll into C#. The c function looks like this

unsigned short write_buffer( unsigned short device_number, unsigned short word_count, unsigned long buffer_link, unsigned short* buffer)

my attempt at a C# import looks like this

[DllImport("sslib32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern ushort write_buffer(ushort deviceNumber, ushort wordCount, UInt32 bufferLink, IntPtr buffer)

In C# i have a Dictionary of messages that i would like to pass to this function. The Dictionary looks like this:

Dictionary<string, List<ushort>> msgs

I am a bit confused how to make a make a proper call to pass msgs as the buffer. deviceNumber is 2, wordCount is 32, and buffLink is 0. So i know the call should look something like this

write_buffer(2,32,0, msgs[key]);

Obviously i am getting an invalid argument for the IntPtr. What is the proper way to make this call?

Upvotes: 0

Views: 1955

Answers (3)

Hans Passant
Hans Passant

Reputation: 942267

It is quite unclear what buffer should contain and in which direction its data flows. Your dictionary suggests it should be an array. Just declare it that way:

 private static extern ushort write_buffer(.., ushort[] buffer);

And use msgs[key].ToArray() in the call.

Using constants in the write_buffer() call does not make that a likely scenario though, there ought to be msgs[key].Count in there somewhere.

Upvotes: 2

driis
driis

Reputation: 164341

If you don't mind marking the code unsafe, you can simply do:

fixed(ushort* pData = msgs[key])
{
    write_buffer(2,32,0, pData);
}

And declare your DllImport to take ushort* as the last argument.

The alternative is to use Marshal.StructureToPtr to get the array marshalled into fixed memory. This requires you to allocate memory first using AllocHGlobal, and freeing using FreeHGlobal.

Upvotes: 0

Steve Townsend
Steve Townsend

Reputation: 54178

You can generate P/Invoke signatures using the P/Invoke Interop Assistant tool that is referenced here.

In the January 2008 issue of the MSDN Magazine, Yi Zhang and Xiaoying Guo have published a CLR Inside Out column on marshaling between managed and unmanaged code. In that column, they introduce the P/Invoke Interop Assistant, an automatic GUI and command-line utility for converting between managed and unmanaged signatures (in both directions). This conversion, of course, is not limited just to Windows signatures; give the tool a snippet of your own C header files and it will dutifully convert them to pretty-printed C# [DllImport]'s.

Upvotes: 1

Related Questions