2017-02-24 95 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