【问题标题】:Calling C++ DLL with a callback function that contains a char* from C#使用包含来自 C# 的 char* 的回调函数调用 C++ DLL
【发布时间】:2012-10-30 02:23:59
【问题描述】:

我有一个 C++ DLL (SimpleDLL.dll),它有一个公开的函数 (DllFunctionPoibnterGetName),它有一个函数指针 (getNameFP) .函数指针将 char * 作为参数 (*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 ); 
}

我有一个想要使用这个 C++ DLL 的 C# 应用程序。

// 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; 
    }   
}

目前我可以毫无问题地设置长度,但我似乎找不到正确设置名称的方法。

我的问题是

  • 如何正确地将 char * 名称设置为一个值。

【问题讨论】:

标签: c# pinvoke


【解决方案1】:

您不需要使用不安全的代码。你可以这样做:

[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);
}   

虽然这个界面设计只是要求缓冲区溢出。你怎么知道非托管缓冲区有多大? length 参数由ref 传递会更有意义。在输入时它会告诉你缓冲区有多大。在输出时,您会记录复制到缓冲区中的字节数。

【讨论】:

  • 您好,谢谢,是的,我意识到如果我不声明缓冲区有多大,我可能会出现缓冲区溢出。
【解决方案2】:

将 char* 转换为 char[]。这应该可以解决问题。

【讨论】:

    【解决方案3】:

    铸造 char 是不行的。 char * 数据是“非托管”的本机数据。而 C# 使用“托管”的 .NET 数据。

    您需要为您的调用创建一个包装器,并使用 marschall 将数据从“非托管”转换为“托管”。

    【讨论】:

    猜你喜欢
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多