0

I am implementing c#.net wrapper for C-based Library. currently, working on function with passing A void pointer, which will set value.

NOTE : void pointer can take different data type depending on Enum.

Objective: to pass void pointer and set value

I checked many solutions to implement and finally came to following state :

The C-dll function:

int function_call(enum a, void * var);

The C function call code:

char name[255];
name = "asd";
function_call(enum a, &name);

The C# wrapper code:

[DllImport("mylibrary.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int function_call(enum a, IntPtr var);

The C# function call code:

IntPtr name;
string val = "asd";
name = Marshal.StringToHGolbalUni(val);
int ret = function_call(Enum_type, name);

By this method it only sets First character a from the input asd.

I have already checked "Duplicate" questions but doesnt solve the issue:

c++ - What is void* in C#

How to declare void pointer in C#

void* in C#

akshay dhule
  • 167
  • 3
  • 17

2 Answers2

3

I would treat your void * as a char * and use

[MarshalAs(UnmanagedType.LPStr)] StringBuilder var

instead of IntPtr

You should find it works as expected, but take care with size of the char array that your C function expects. Perhaps an explicit size in your declaration of your StringBuilder variable before you call the C function like this:

StringBuilder newvar= new StringBuilder(512);

Good link explaining the circumstances where StringBuilder is used instead of String or IntPtr is explained here - Thanks Amy for the link

Grantly
  • 2,546
  • 2
  • 21
  • 31
  • Do you mean `String` instead of `StringBuilder`? –  Nov 17 '17 at 22:33
  • Nope. StringBuilder – Grantly Nov 17 '17 at 22:35
  • Why would you use `StringBuilder` here? –  Nov 17 '17 at 22:36
  • Because it works with Importing C libraries with CDecl into C#. What do you use? – Grantly Nov 17 '17 at 22:37
  • Nothing. That's why I'm asking. I would expect `String` to be used. –  Nov 17 '17 at 22:38
  • 1
    I found [this](https://limbioliong.wordpress.com/2011/11/01/using-the-stringbuilder-in-unmanaged-api-calls/) which explains why you used `StringBuilder`. –  Nov 17 '17 at 22:39
  • 2
    @Grantly If you provide a different answer from what a reasonable programmer could expect, it's only natural that you'll receive comments asking you why you're saying what you're saying. Refusing to answer those comments makes your answer pretty useless. Readers have no way of knowing whether this answer is any good. –  Nov 17 '17 at 22:41
  • I'll admit, I was frustrated having to go elsewhere to get my "why do you do this" question answered. –  Nov 17 '17 at 22:42
  • 1
    @Amy That explains why `StringBuilder` is used when copying strings from unmanaged code to managed code. The OP here is copying strings from managed code to unmanaged code. I think you had it right the first time, that's no reason to use `StringBuilder`. –  Nov 17 '17 at 22:43
  • @hvd That only heightens the frustration. If the OP had answered my question instead of asserting how unambiguous his question was, I wouldn't have found the wrong document. I'm tempted to downvote over this. –  Nov 17 '17 at 22:44
  • My apologies, based on the coding style in the OP (using = for a char array in C), I considered a short and concise answer that could be tested very fast by the Asker, and would respond as expected in all circumstances (unman to man, man to unman code, etc) - would suit the Asker better. The reason why to use SB can be very drawn out and complicated, as explained in your link Amy. I will Edit the Answer – Grantly Nov 17 '17 at 22:48
0

The Issue was resolved with :

[DllImport("mylibrary.dll", CharSet = CharSet.Ansi,  CallingConvention = CallingConvention.Cdecl)]

and

name = Marshal.StringToHGolbalAnsi(val);

On client side :

IntPtr nameptr;
string name = "asd";
nameptr= Marshal.StringToHGlobalAnsi(name);
akshay dhule
  • 167
  • 3
  • 17