Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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#:如何设置不安全结构的成员数组 我正在研究一个VS 2015 MVC C++ Web应用程序,它加载了一个第三方C++ DLL,我没有源码。DLL需要一个输入参数。新规范需要两个数组成员。一个是int数组,另一个是char数组 < >我的C结构将定义的 char < /C>数组作为字节 >与8位C++ char:匹配。 [StructLayout(LayoutKind.Sequential)] public unsafe struct MyDLLInput { public fixed int SomeList[288]; public fixed byte PathToData[256]; };_C#_C++ - Fatal编程技术网

C#:如何设置不安全结构的成员数组 我正在研究一个VS 2015 MVC C++ Web应用程序,它加载了一个第三方C++ DLL,我没有源码。DLL需要一个输入参数。新规范需要两个数组成员。一个是int数组,另一个是char数组 < >我的C结构将定义的 char < /C>数组作为字节 >与8位C++ char:匹配。 [StructLayout(LayoutKind.Sequential)] public unsafe struct MyDLLInput { public fixed int SomeList[288]; public fixed byte PathToData[256]; };

C#:如何设置不安全结构的成员数组 我正在研究一个VS 2015 MVC C++ Web应用程序,它加载了一个第三方C++ DLL,我没有源码。DLL需要一个输入参数。新规范需要两个数组成员。一个是int数组,另一个是char数组 < >我的C结构将定义的 char < /C>数组作为字节 >与8位C++ char:匹配。 [StructLayout(LayoutKind.Sequential)] public unsafe struct MyDLLInput { public fixed int SomeList[288]; public fixed byte PathToData[256]; };,c#,c++,C#,C++,结构对我来说似乎是正确的,但现在我需要设置值,我没有任何成功 MyDLLInput dllInput = new MyDLLInput() { SomeList = new int[] {0,12,33,67,93}, PathToData = "C:\\some\\path\\to\\data" } // Call 3rd Party DLL MyDLLOutput = MyDLL.EntryPoint(MyDLLInput); 对于这两个成员数组,我得到以下错误: 只能通

结构对我来说似乎是正确的,但现在我需要设置值,我没有任何成功

MyDLLInput dllInput = new MyDLLInput()
{
    SomeList = new int[] {0,12,33,67,93},
    PathToData = "C:\\some\\path\\to\\data"
}

// Call 3rd Party DLL
MyDLLOutput = MyDLL.EntryPoint(MyDLLInput);
对于这两个成员数组,我得到以下错误:

只能通过局部变量或字段访问固定大小的缓冲区

这里至少有几件事情在进行——除了使用本地设置值的正确方法之外,我还必须进行编码转换,从
string
byte[]


有人能给我提供一个干净的方法来设置这些值的代码示例吗?

使用不安全的结构有什么原因吗?不能使用编组属性吗?看

无论如何,你需要知道如何从C字符串转换成字节数组,这取决于C++ C++中对字符串的编码。例如,在Windows上,它通常是“ANSI代码页”,但在Linux/Unix上,它可能是“当前语言环境”或显式的“UTF-8”

因此,让您对编码进行最大控制的一个选项是:

    [StructLayout(LayoutKind.Sequential)]
    public struct MyDllInput
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 288)]
        public int[] SomeList;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
        public byte[] PathToData;
    }
    public static void Main()
    {
        MyDllInput dllInput = new MyDllInput()
        {
            SomeList = new int[288],
            PathToData = new byte[256]
        };

        var listData = new int[] { 0, 12, 33, 67, 93 };
        Array.Copy(listData, dllInput.SomeList, listData.Length);

        var pathToDataBytes = Encoding.UTF8.GetBytes("C:\\some\\path\\to\\data");
        Array.Copy(pathToDataBytes, dllInput.PathToData, pathToDataBytes.Length);
    }
或者,您可以尝试将PathToData声明为字符串,然后使用编组属性让C#为您转换,而不是直接进行编码转换;见:

在第二种情况下,当您声明EntryPoint时,必须在DllImportAttribute上设置CharSet属性,以使字符串转换按您希望的方式进行。在您的情况下,您可能需要CharSet.Ansi,因为您的DLL采用char*而不是wchar\u t*。比如说,

    [DllImport("MyDll.dll", CharSet = CharSet.Ansi)]
    private static extern void EntryPoint(ref MyDllInput input);

您需要在不安全的block.Encoding.GetBytes中实例化固定字段,这将解决您的第二个问题您的示例非常好,我希望它对我有用。我现在不能尝试,但我会晚一点到我的办公桌。至于使用编组属性,这是另一个选项,我不确定如何设置,项目已接近预定的截止日期。一旦我把一切都做好了,我就不去管它去赶最后期限了。我将尝试你的建议,并将在今晚晚些时候提供更新。谢谢你抽出时间。我非常感谢您的帮助。我正在尝试您的第一个示例,但我收到的
类型无法封送,因为嵌入数组实例的长度与布局中声明的长度不匹配。
这是因为我的
int[]SomeList
在数组中不包含288个元素和/或
byte[]PathToData
不完全是256字节?SomeList并不总是用288个元素初始化——有时只有1个元素,当然,PathToData的长度不完全是256字节。我只是想知道这是否是我得到错误的原因,如果是的话,如何克服?我想你是对的——我假设C#会对数组进行零扩展,但我猜它不会自动这样做。您可以尝试手动将阵列扩展到正确的大小。例如,您可以分配一个大小正确的数组,然后使用array.copy()从较小的数组复制到大小正确的数组。我知道这个问题已标记为已回答。也许我应该问一个新的,但我认为这是相关的。当我调用DLL的入口点时,我得到一个异常-
方法的类型签名与PInvoke不兼容。
我读过其他SO问题/答案,但看不出它们有什么帮助。你明白我为什么会收到这个错误吗?请记住,我不能访问第三方DLL的C++源代码。如果你认为我应该的话,我会问一个新问题。我在这里问了一个新问题:
    [DllImport("MyDll.dll", CharSet = CharSet.Ansi)]
    private static extern void EntryPoint(ref MyDllInput input);