Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 元帅常量字符**_C#_Marshalling - Fatal编程技术网

C# 元帅常量字符**

C# 元帅常量字符**,c#,marshalling,C#,Marshalling,我正在为Arma 3写一个扩展。通常你可以简单地写一个C++库,然后实现这个函数 int __stdcall RVExtensionArgs(char *output, int outputSize, const char *function, const char **args, int argCnt); 我正在开发一个C#库,我想在其中实现这个功能。函数RVExtensionArgs有一个修饰名_RVExtensionArgs@20用于32位,而RVExtensionArgs用于64位 我

我正在为Arma 3写一个扩展。通常你可以简单地写一个C++库,然后实现这个函数

int __stdcall RVExtensionArgs(char *output, int outputSize, const char *function, const char **args, int argCnt);
我正在开发一个C#库,我想在其中实现这个功能。函数
RVExtensionArgs
有一个修饰名
_RVExtensionArgs@20
用于32位,而
RVExtensionArgs
用于64位

我正在处理args参数的const char的指针。我当前的实现是

#if WIN64
    [DllExport("RVExtensionArgs", CallingConvention = CallingConvention.Winapi)]
#else
    [DllExport("_RVExtensionArgs@20", 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来自

这里有一些关于扩展的信息


但这样游戏就崩溃了。我很确定这是因为args,但我无法验证它。我是否漏掉了什么东西?

< p>我在对问题的评论中回答了这个问题,但是想指出,从代码C到C++的最简单的导出代码< const char *>代码>是一个<代码>字节**/COD> 我创建了下面的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;
    }
}
公共不安全静态类StringMarshaller
{
公共静态字符串[]封送处理(字节**nativeStrings,int stringCount)
{
变量字符串=新字符串[stringCount];
对于(变量x=0;x
将其作为byte*output、int-outputSize、byte*function、byte**args、int-argCnt导入一个不安全的类,以消除封送过程中的猜测,不是更简单、更高效吗?唯一的“挑战”是将.NET字符串中的UTF-16字符转换为字节。@hoodaticus我对我得到的每个解决方案都持开放态度。你能给我一些关于如何实现你的想法的信息吗?等等——为什么你在C++中使用STDCALL时指定WiNAPI调用约定?@ HooDATIUS是的,我做得很好。我只是想知道如何将字节**转换成字符串array@chris579-我会这样做并更新您。结果是我必须使用CallingConvention.Winapi或dll无法识别和加载。我建议进行编辑,因为您当前的示例不起作用:)@chris579-抱歉,评审委员会在我之前进行了编辑,并拒绝了它。我不知道为什么你的改变是必要的,但重要的是你让它工作起来了。您现在还好吗?需要进行编辑,因为Encoding.UTF8.GeString无法直接处理字节指针。必须首先将其封送到字节数组。但是很好now@chris579-啊,您必须使用.NET 4.0或更早版本。最新版本确实接受GetString重载中的原始字节指针。顺便说一句,祝贺你度过了这一关!这不是一个容易的问题-你应该感到自豪。嗯,我在4.5上,编译器给我带来了一些错误。Nvm,它现在可以工作了,这是主要的一点。谢谢你的夸奖,通常我在C#方面没有什么大问题,但是当涉及到导出、导入和dll接口时,我的工作非常紧张