BSTR type in vc#

I received a DLL which uses BSTR as string type:

example : given in the include file

DLLEXPORT BSTR WINAPI I2cGetInterfaceTypeStr (BSTR Interface);

how do i access this function in vc#. This doesn't work.

[DllImport("I2CAPI32.dll")]publicstaticexternstring I2cGetInterfaceTypeStr (string Interface);

Other functions of the DLL which don't use BSTR are working ok.

Can anyone help me.

Thanks, Jan

[787 byte] By [jan_hk] at [2008-2-14]
# 1

The DllImport attribute assumes ANSI strings. If you incorrectly match the character set of strings in function signatures you will get undefined behavior. Since BSTR is (almost always) used to store Unicode strings you need to specify this explicitly as follows:

[DllImport("I2CAPI32.dll", CharSet=CharSet.Unicode)]
public static extern string I2cGetInterfaceTypeStr(string Interface);

Cheers,
Kenny Kerr

http://weblogs.asp.net/kennykerr

KennyKerr at 2007-9-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 2
Hello Kenny

Thanks for the advice. I have however still a problem with an empty string.
In the C++ example the command is

// get first interface from the registry
// (first interface is returned when passing an empty string ! )
InterfaceGUID = I2cGetNextInterface( (BSTR)(""));
while(1)
{
// compare the interface found in the registry with ’cIFType’ (the one we want to use )
if (!strcmp(cIFType, (const char*)I2cGetInterfaceTypeStr(InterfaceGUID)))
break;

but
FirstGUID = I2cGetNextInterface((string)""); // returns also empty sting

FirstGUID = I2cGetNextInterface("{00DA5BA0-2540-11d1-8110-00400534438D}"); // returns next key from the register

Any idea how to cast empty string.

Thanks, Jan




jan_hk at 2007-9-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 3

Ah, you’re using types incorrectly in C++ giving you the behavior you desire and want to reproduce that in C#. I’m afraid I can’t help you. You need to go back to the drawing board and figure out what on earth you’re doing.

Firstly you’re attempting to create a BSTR simply by casting an ANSI string as the parameter to your imported function. This is incorrect. BSTRs are allocated using the SysAllocString function.

Secondly you’re casting the BSTR returned by the function to an ANSI string which is again incorrect. BSTRs need to be freed using the SysFreeString function.

As I said in my original post answering your question, if you incorrectly match the character set of strings in function signatures you will get undefined behavior.

.NET P/Invoke along with DllImport will correctly deal with all the marshalling for you provided you’re not wishing to reproduce incorrect code, which appears to be the case here.

KennyKerr at 2007-9-8 > top of Msdn Tech,Visual C#,Visual C# Language...
# 4
Hello Kenny

The VC++ example was included with the DLL.

and to summarize.

[DllImport("I2CAPI32.dll", CharSet=CharSet.Ansi)] works
[DllImport("I2CAPI32.dll", CharSet=CharSet.Unicode)] doesn't work

As far as i know is string unicode and not ansi string.
BSTR is also unicode.
Very strange to me that Charset.Unicode doesn't work.

But anyhow thanks for you help. I found something about Platform invoke and Marshaling but it is very complex for me.

Thanks, Jan

jan_hk at 2007-9-8 > top of Msdn Tech,Visual C#,Visual C# Language...