2017-02-24 124 views
2

我正在寫阿瑪3.擴展通常情況下,你可以簡單地寫一個C++庫,這和剛剛實現這個功能元帥爲const char **

int __stdcall RVExtensionArgs(char *output, int outputSize, const char *function, const char **args, int argCnt); 

我正在開發一個C#庫,我想把它實現這個功能。功能RVExtensionArgs具有修飾名是[email protected]爲32位和RVExtensionArgs 64位

我正在與指針args參數的常量字符的指針掙扎。我當前的實現是

#if WIN64 
    [DllExport("RVExtensionArgs", CallingConvention = CallingConvention.Winapi)] 
#else 
    [DllExport("[email protected]", CallingConvention = CallingConvention.Winapi)] 
#endif 
    public static int RvExtensionArgs(StringBuilder output, int outputSize, 
     [MarshalAs(UnmanagedType.LPStr)] string function, 
     [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4, ArraySubType = UnmanagedType.LPStr)] string[] args, 
     int argCount) 

的DLLEXPORT使用的是從UnmanagedExports

有關於在here

擴展,但這樣的遊戲崩潰的一些信息。我很確定這是因爲參數,但我無法驗證它。我錯過了什麼嗎?

+0

你會得到任何異常信息嗎? – pquest

+0

可悲的是,沒有有用的調試信息。在這種情況下,我無法調試任何東西,因爲dll是從遊戲加載的,當然遊戲無法調試。我也實現了正常的RVExtension(可以在維基頁面找到我鏈接),這工作正常。 – chris579

+2

將它導入一個不安全的類中會不會更簡單和更高性能:byte * output,int outputSize,byte * function,byte ** args,int argCnt將猜測帶出編組?唯一的「挑戰」是將.NET字符串中的UTF-16字符轉換爲字節。 – hoodaticus

回答

1

我在問題的評論中回答了這個問題,但想指出將const char**從C#導出到C++的最簡單方法是byte**

我已經創建了下面的StringMarshaller類來幫助您將字節**轉換爲字符串[]。我還沒有測試過 - 我可能有時間以後再更新,如果是的話。

public unsafe static class StringMarshaller 
{ 
    public static string[] Marshal(byte** nativeStrings, int stringCount) 
    { 
     var strings = new string[stringCount]; 

     for (var x = 0; x < stringCount; ++x) 
     { 
      if (nativeStrings[x] == null) continue; 
      var length = GetStringLength(nativeStrings[x]); 
      strings[x] = length == 0 
        ? string.Empty 
        : Encoding.UTF8.GetString(nativeStrings[x], length); 
     } 

     return strings; 
    } 

    public static int GetStringLength(byte* nativeString) 
    { 
     var length = 0; 

     while (*nativeString != '\0') 
     { 
      ++length; 
      ++nativeString; 
     } 

     return length; 
    } 
} 
+1

事實證明,我將不得不使用CallingConvention.Winapi或dll不被識別和加載。我提出了一個編輯,因爲你目前的例子不起作用:) – chris579

+0

@ chris579 - 對不起,審查委員會在我做之前已經進行了編輯並拒絕了它。我不確定爲什麼你的改變是必要的,但重要的是你有它的工作。你現在好嗎? – hoodaticus

+1

編輯是需要的,因爲Encoding.UTF8.GeString不能直接處理字節指針。它必須首先編組到一個字節數組。但現在沒關係 – chris579