tags:

views:

708

answers:

3

I'm attempting to call a 3rd-party DLL from C#, and I'm having trouble marshalling some string data. The DLL was written with Clarion, and I'm not very familiar with the data types being used. Specifically, the spec has this signature for a function that I can't get to work:

Bool QuerySoftwareVersion( cstring* version)  // edited documentation typo
//Returns Software version (20 character cstring).

I was assuming that the cstring was just a null-terminated string, but I wasn't able to get it to work with out char[] version in my definition. Anyone know the right way to handle this?

EDIT: Actually, what I've found thus far suggests that a cstring in Clarion is indeed just a null-terminated string.

UPDATE: I've updated the title of the question and the details because it turns out that there was a typo in the DLL documentation. The version parameter in question is declared as type cstring* not cstringt*. And in Clarion, cstring` is apparently just a c-style, null-terminated string. So the marshalling shouldn't be that complicated, since they claim it was written with C calling conventions. Has anyone successfully p/invoked a Clarion DLL that passes strings via a reference param?

A: 

Try with a StringBuilder:

[DllImport("mylibrary.dll")]
static extern bool QuerySoftwareVersion([Out] StringBuilder version);
Darin Dimitrov
This approach gets a value back, but the string is just a few weird characters. Changing the CharSet attribute or MarshalAs type doesn't seem to fix it.
Abs
A: 

Has this been resolved? I am working on the exact same problem. Thanks in advance for any info.

A: 

I've never called into Clarion, but I've got a DLL (in C) that is called from both Clarion and C#, and I'd interop that as:

[DllImport("clarionlib.dll", CharSet=CharSet.Ansi,
CallingConvention = CallingConvention.Cdecl,
ExactSpelling=true, EntryPoint="QuerySoftwareVersion")] static extern
            bool QuerySoftwareVersion(StringBuilder sName);

Note also that the StringBuilder parameter you pass has to be sized up to the maximum expected return size (pardon my C#, I'm sure there's a shorter equivalent):

System.Text.StringBuilder buffer;
buffer = new System.Text.StringBuilder();
buffer.EnsureCapacity(21);
QuerySoftwareVersion(buffer);
string = buffer.ToString();
Spike0xff