1

I have a C++ DLL (SimpleDLL.dll), with a exposed function (DllFunctionPoibnterGetName) that has a function pointer (getNameFP). The function pointer takes a char * as a parameter (*char * name*).

// C++ 
DllExport void DllFunctionPoibnterGetName( void (*getNameFP) (char * name, unsigned short * length ) ) {

    char name[1024];
    unsigned short length = 0 ; 
    getNameFP( name, &length ); 

    printf( "length=[%d] name=[%s]\n", length, name ); 
}

I have a C# application that would like to use this C++ DLL.

// C# 
public unsafe delegate void GetName( System.Char* name, System.UInt16* length); 
unsafe class Program
{
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void delegateGetName(System.Char* name, System.UInt16* length);

    [DllImport("SimpleDLL.dll", CharSet = CharSet.Ansi )]
    public static extern void DllFunctionPoibnterGetName([MarshalAs(UnmanagedType.FunctionPtr)] delegateGetName getName);

    static void Main(string[] args)
    {   
        DllFunctionPoibnterGetName(GetName); 
    }

    static void GetName(System.Char* name, System.UInt16* length)
    {
        // name = "one two three";
        *length = 10; 
    }   
}

Currently I can set the length with out any problems, but I can't seem to find a way to set the name correctly.

My Question is

  • How do I set the char * name to a value correctly.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Steven Smethurst
  • 4,495
  • 15
  • 55
  • 92
  • consult http://stackoverflow.com/questions/6282264/pass-a-function-pointer-from-c-to-be-called-by-c-sharp-arguments-of-function – avishayp Nov 09 '12 at 18:35

3 Answers3

1

Cast the char* as a char[]. That should do the trick.

Jordan Lapp
  • 982
  • 9
  • 19
1

Casting the char will not do. The char * data is 'unmanaged', native data. And C# uses 'managed', .NET data.

You need to make a wrapper for your call and use marschall to convert the data from 'unmanaged' to 'managed'.

PapaAtHome
  • 575
  • 8
  • 25
  • 1
    This should help: http://stackoverflow.com/questions/5308584/how-to-return-text-from-native-c-code – Cypher Nov 09 '12 at 18:43
1

You don't need to use unsafe code. You can do it like this:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void delegateGetName(IntPtr name, out ushort length);
....
static void GetName(IntPtr name, out ushort length)
{
    byte[] buffer = Encoding.Default.GetBytes("one two three");
    length = (ushort)buffer.Length;
    Marshal.Copy(buffer, 0, name, buffer.Length);
}   

Although this interface design is just asking for a buffer overrun. How are you supposed to know how big the unmanaged buffer is? It would make more sense for the length parameter to be passed by ref. On input it would tell you how big the buffer is. On output you would have recorded how many bytes you copied into the buffer.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490