【发布时间】:2021-06-02 22:38:29
【问题描述】:
我从 .so lib 中调用一个方法,该方法是使用 C# 用 C 编写的。这就是使用的 C# 代码:
[DllImport("liblab.so")]
static extern char[] entrance(
[MarshalAs(UnmanagedType.LPWStr)]string path,
[MarshalAs(UnmanagedType.LPWStr)]string command);
static void Main(string[] args)
{
command = Console.ReadLine();
output = entrance(path, command).ToString();
Console.WriteLine(output);
}
(路径是那里的硬编码字符串)。
这就是在 C 中调用的代码:
char* entrance(char* path, char* command1){
struct state* fs_state = setup(path);
if (fs_state != NULL){
fgets_wrapper(command1, LINE_MAX, stdin);
struct commands command = parse_command(command1);
return execute_operation(command, fs_state);
}
else return "No data";
}
从 C# 函数 entrance 调用会导致 Unhandled exception. System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'return value': Invalid managed/unmanaged type combination. 错误。我尝试了不同的编码,但它们都不起作用。
我该如何解决?
【问题讨论】:
-
如果在 C# 中
char*是string用于参数(这是合乎逻辑的),为什么不同时使用string作为返回类型呢?为什么是char[]?那不是一回事,不是吗? PInvoke char* in C DLL handled as String in C#. Issue with null characters | How To P/Invoke char*[] in C# -
toString() 不会这样工作吗?
-
所以是的,我在这里使用 ToString() 将 char[] 返回类型转换为字符串。您认为在 DllImport 中为
entrance使用 MarshalAs 更好吗? -
我在 P/Invoke 方面并不是很先进,只使用了一些预定义的 WinAPI 签名,但正如我所说,它看起来像你需要的:
static extern string entry (...),你将在没有 ToString 的情况下使用它,因为返回类型和参数一样,而且必须一致,全部使用相同的类型,对吧? -
假设字符串在 C 端是 ANSI,那么声明应该是
[DllImport("liblab.so")] [return: MarshalAs(UnmanagedType.LPStr)] static extern string entrance( [MarshalAs(UnmanagedType.LPStr)] string path, [MarshalAs(UnmanagedType.LPStr)] string command);
标签: c# c shared-libraries dllimport