繁体   English   中英

导出托管的C#函数以将更改的char *参数返回到非托管代码

[英]Export managed C# function to return changed char* parameter to unmanaged code

我有一个本地C ++(我认为)应用程序,可以将其配置为加载某个dll并调用一个函数。 此函数返回int,接受四个参数,应更改两个参数中的至少一个并返回一个值。 根据手册,此功能应在C ++中定义为:

__declspec( dllexport ) int funcName(const char* par1, const char* par2, char* par3, char* par4);

但是,根据需要,此功能应在C#中实现。 我正在使用“不受管理的导出”来允许我使用:

[DllExport("funcName", CallingConvention.Cdecl)]
public static unsafe int funcName(string par1, string par2, string par3, string par4) {
    // sample for par3 only when using StringBuilder instead of string
    // but is similar with other types
    par3 = new StringBuilder(256); 
    par3.Append("12345"); 
    return 0; 
}

参数1和2可以正常工作(我可以在消息框中输入接收到的值),但是我已经尝试(至少)将以下参数用作第3和第4个参数:

char* =>
=> string
=> StringBuilder
=> char[]

所有这些都带有[In], [Out], [In,Out], out, ref

函数应更改par3和par4的值,并将整数返回给调用应用程序。 应用程序读取par3的值(它实际上是一个表示为字符串的整数),并将其写到日志文件中。 检查日志文件后,该值不是funcName(...)中设置的值。

最通常的值是“”(空),但是仅当使用带outref char[]out似乎才传回了一个值,但这只是一些奇怪的chars(不是funcName中设置的值)。

因此问题是,从非托管代码调用托管dll函数时如何返回char *参数?

我非常怀疑UnmanagedImports将为您完成这项工作。 除非我非常误解,否则它不会使StringBuilder成为现实。 我认为您需要这样编码:

[DllExport("funcName", CallingConvention.Cdecl)]
public static int funcName(string par1, string par2, IntPtr par3, IntPtr par4) 
{
    string inputStr = Marshal.PtrToStringAnsi(par3);
    string outputStr = "foo\0";
    byte[] outputBytes = Encoding.Default.GetBytes(outputStr);
    Marshal.Copy(outputBytes, 0, par3, outputBytes.Length);
    return 0; 
}

请注意,我已删除了unsafe因为这是不必要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM