![](/img/trans.png)
[英]System.EntryPointNotFoundException error in SWIG on mono 2.8
[英]in linux, mono invoke my .so lib return System.EntryPointNotFoundException
這是我的C ++代碼
#include "_app_switcher.h"
std::string c_meth(std::string str_arg) {
return "prpr";
}
我的單聲道代碼:
[Test]
public void TestDraft()
{
Console.WriteLine(c_meth("prpr"));
}
[DllImport("/home/roroco/Dropbox/cs/App.Switcher/c/app-switcher/lib/libapp-switcher-t.so")]
private static extern string c_meth(string strArg);
錯誤輸出:
System.EntryPointNotFoundException : c_meth
at (wrapper managed-to-native) Test.Ro.EnvTest.c_meth(string)
at Test.Ro.EnvTest.TestDraft () [0x00001] in /home/roroco/Dropbox/cs/Ro/TestRo/EnvTest.cs:15
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <71d8ad678db34313b7f718a414dfcb25>:0
我猜這是因為我的頭文件不在/ usr / include中,所以如何在mono中指定c ++頭文件?
您的代碼無法正常工作的原因有兩個:
c_meth
在共享庫中不存在。 確實存在的函數是_Z6c_methNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
。 std::string
和.NET類System.String
是不同的,並且完全不相關。 .NET僅知道如何將System.String
為const char*
,反之亦然。 C ++允許函數重載。 這意味着它需要一種方法來區分void foo(int)
和void foo(std::string)
。 為此,它使用名稱修飾為每個重載生成唯一的名稱。 要禁用功能的名稱修飾,請使用extern "C"
說明符對其進行聲明。 這也將您限制為類似C的接口,因此您只能傳遞和返回原始對象和指針。 沒有類別或參考。 不過,這很好,因為.NET不知道如何處理C ++類。 您需要接受一個原始的const char*
參數並返回一個const char*
:
extern "C" const char* c_meth(const char* str_arg) {
return "prpr";
}
返回字符串也是有問題的。 將字符串復制到托管堆后,.NET將嘗試取消分配返回的內存。 由於在這種情況下返回的字符串未使用適當的分配方法進行分配,因此將失敗。 為避免這種情況,您需要在C#中聲明導入的方法以返回IntPtr
並使用Marshal.PtrToString(Ansi|Unicode)
轉換為System.String
。
如果確實需要返回字符串常量以外的其他值,則有兩種選擇:
System.Text.StringBuilder
在C#中分配內存,並將緩沖區傳遞給非托管函數: C ++方面:
extern "C" void c_meth(const char* str_arg, char* outbuf, int outsize) {
std::string ret = someFunctionThatReturnsAString(str_arg);
std::strncpy(outbuf, ret.c_str(), outsize);
}
C#端:
[Test]
public void TestDraft()
{
StringBuilder sb = new StringBuilder(256)
c_meth("prpr", sb, 256);
Console.WriteLine(sb.ToString());
}
[DllImport("/home/roroco/Dropbox/cs/App.Switcher/c/app-switcher/lib/libapp-switcher-t.so")]
private static extern void c_meth(string strArg, StringBuilder outbuf, int outsize);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.