DllImport Char* and string

G

Gnic

Hi,

I have a (Complied) C Library that needs to be called using c# code, some of
the function require char* parameter(in and out)

Here is the problem,

There is a function that expect an input char* parameter

for example
int AddString(const char* someStr)

And then there is another function to retrieve the value I pass in using the
above function
for example
int GetString(char* rntStr)

In C#

[DllImport(......)]
Int32 AddString(string someStr);

[DllImport(..)]
Int32 GetString(string rntString);

So when I input "aaaa" into someStr and get the return by calling GetString,
the rntString variable only return the first character ("a") and the length
of the string is 1.

Anyone know what's wrong with my code?
It the AssString declaration problem or the GetString declaration problem
(or both)?

thanks

Gasnic
 
L

Light

Yes, I do. You may have to set the Char type in the DllImport to
probably Ansi. Try that. If anyone reads this and gets an example for
char** and also for bools in a C++ struct then would like to see an
example of that. I think I know how to do it though.
Curtis
http://www.ghostclip.com
The Premier Help System For Developers
 
G

Gnic

I have tried to declare the function like this

Int32 AddString([MarshalAs(UnmanagedType.AnsiBStr) string someStr)

Int32 GetString([MarshalAs(UnmanagedType.AnsiBStr) ref string rntStr)

But I got the same thing.

I also tried UnmanagedType.LPStr and UnmanagedType.LPTStr, but both doesn't
work.

Actually should I use string as the parameter type?

thanks

Gnic
 
M

Mattias Sjögren

[DllImport(..)]
Int32 GetString(string rntString);

For output string parameters you should use StringBuilder as the
parameter type.

Also make sure that if you set the CharSet property in the DllImport
attribute, it should be set to Ansi.


Mattias
 
J

James Park

Mattias Sjögren said:
[DllImport(..)]
Int32 GetString(string rntString);

For output string parameters you should use StringBuilder as the
parameter type.

Also make sure that if you set the CharSet property in the DllImport
attribute, it should be set to Ansi.

Doesn't C# default to CharSet.Ansi?
 
M

Mattias Sjögren

Doesn't C# default to CharSet.Ansi?

It does, but since the original poster wrote

[DllImport(..)]

I couldn't know for sure whether or not he or she left the default or
specified something else.


Mattias
 
?

=?Windows-1252?Q?Jos=E9_Manuel_Ag=FCero?=

Hello Gnic,

I'm not a C programmer, but I think that's the expected behaviour: Your C library has a return value of char*, not char[]*.

Regards.


"Gnic" <[email protected]> escribió en el mensaje | Hi,
|
| I have a (Complied) C Library that needs to be called using c# code, some of
| the function require char* parameter(in and out)
|
| Here is the problem,
|
| There is a function that expect an input char* parameter
|
| for example
| int AddString(const char* someStr)
|
| And then there is another function to retrieve the value I pass in using the
| above function
| for example
| int GetString(char* rntStr)
|
| In C#
|
| [DllImport(......)]
| Int32 AddString(string someStr);
|
| [DllImport(..)]
| Int32 GetString(string rntString);
|
| So when I input "aaaa" into someStr and get the return by calling GetString,
| the rntString variable only return the first character ("a") and the length
| of the string is 1.
|
| Anyone know what's wrong with my code?
| It the AssString declaration problem or the GetString declaration problem
| (or both)?
|
| thanks
|
| Gasnic
 
G

Gnic

Thanks for all the helps, I have the problem fixed by using StringBuilder.

But now I have another problem:

The C Library have a struct that contain a unsigned char* field.
I read the MSDN PInvoke doc and it said unsigned char should map to byte in
..NET.
But what about unsigned char*?

should I use byte[] in the class in .NET ( but then I don't know the length
in advance and I have to pass the unsigned char* for the c library to fill
some data in)?

any comment?

thanks
 
J

James Park

Gnic said:
I have tried to declare the function like this

Int32 AddString([MarshalAs(UnmanagedType.AnsiBStr) string someStr)

Int32 GetString([MarshalAs(UnmanagedType.AnsiBStr) ref string rntStr)

But I got the same thing.

I also tried UnmanagedType.LPStr and UnmanagedType.LPTStr, but both
doesn't work.

Actually should I use string as the parameter type?

Mattias already suggested using StringBuilder for your GetString function
since the contents of the buffer look like it needs to be modified.

Here's an example of some code that works. Hopefully it will be somewhat
applicable to what you want to do:

..CPP file:
#include <windows.h>

char m_Text[1000];

extern "C" __declspec(dllexport)
int AddString(const char* someStr)
{
strcpy(m_Text, someStr);
return 0;
}

extern "C" __declspec(dllexport)
int GetString(char* rntStr)
{
strcpy(rntStr, m_Text);
return 0;
}

..CS file:
using System.Text;
using System.Runtime.InteropServices;

class Program
{
[DllImport("CoolStringLibrary.dll")]
static extern int AddString(string someStr);

[DllImport("CoolStringLibrary.dll")]
static extern int GetString(StringBuilder rntStr);

static void Main(string[] args)
{
AddString("aaaa");
StringBuilder rntStr = new StringBuilder();
GetString(rntStr);
}
}
 
J

James Park

Gnic said:
Thanks for all the helps, I have the problem fixed by using StringBuilder.

But now I have another problem:

The C Library have a struct that contain a unsigned char* field.
I read the MSDN PInvoke doc and it said unsigned char should map to byte
in .NET.
But what about unsigned char*?

should I use byte[] in the class in .NET ( but then I don't know the
length in advance and I have to pass the unsigned char* for the c library
to fill some data in)?

any comment?

I think you need to use IntPtr. Marshal.AllocHGlobal(),
Marshal.FreeHGlobal(), Marshal.ReadByte(), and Marshal.WriteByte() should
help you out.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top