Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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.DLL_C#_Marshalling - Fatal编程技术网

发出编组C#结构以调用C.DLL

发出编组C#结构以调用C.DLL,c#,marshalling,C#,Marshalling,我在尝试封送一个我在C#程序中定义的结构时遇到了困难,该结构是调用非托管C.DLL文件所必需的,我没有访问源代码的权限。示例非托管C程序C程序可以毫无问题地调用此.DLL。问题结构如下表所示。我遇到问题的结构中包含多个子结构: 从C头文件: struct fa_keypart { short kp_start; short kp_leng; long kp_flags;

我在尝试封送一个我在C#程序中定义的结构时遇到了困难,该结构是调用非托管C.DLL文件所必需的,我没有访问源代码的权限。示例非托管C程序C程序可以毫无问题地调用此.DLL。问题结构如下表所示。我遇到问题的结构中包含多个子结构:

从C头文件:

struct fa_keypart {
    short kp_start;                      
    short kp_leng;                       
    long  kp_flags;                    
};


struct fa_keydesc {
    long  k_flags;                       
    long  k_nparts;                      
    struct fa_keypart k_part [FA_NPARTS];                                        
};


struct fa_keylist {
    long  kl_nkeys;                     
    char  kl_reserve[4];                
    struct fa_keydesc *kl_key [FA_NKEYS];
}
在C#中,我将其定义为:

    [StructLayout(LayoutKind.Sequential)]
    public struct fa_keypart
    {
        public Int16 kp_start;                            
        public Int16 kp_leng;                                       
        public Int32 kp_flags;                      
    }


    [StructLayout(LayoutKind.Sequential)]
    public struct fa_keydesc
    {
        public Int32 k_flags;                            
        public Int32 k_nparts;                                
        [MarshalAs(UnmanagedType.ByValArray)]
        public fa_keypart[] kparts;
    };


    [StructLayout(LayoutKind.Sequential)]
    public struct fa_keylist
    {
        public Int32 kl_nkeys;                                  
        public UInt32 kl_reserve;                              
        [MarshalAs(UnmanagedType.ByValArray)]
        public fa_keydesc[] kl_keys;    
    }
    [STAThread]
    [DllImport("F4AGFCFA.dll", EntryPoint = "cobfa_open", CallingConvention = CallingConvention.StdCall)]
    public static extern Int32 cobfa_open(
                        string fileName,
                        Int32 openFlags,
                        ref fa_keylist keyList,
                        Int32 recordLength);
实际调用的DLLIMPORT签名定义为:

    [StructLayout(LayoutKind.Sequential)]
    public struct fa_keypart
    {
        public Int16 kp_start;                            
        public Int16 kp_leng;                                       
        public Int32 kp_flags;                      
    }


    [StructLayout(LayoutKind.Sequential)]
    public struct fa_keydesc
    {
        public Int32 k_flags;                            
        public Int32 k_nparts;                                
        [MarshalAs(UnmanagedType.ByValArray)]
        public fa_keypart[] kparts;
    };


    [StructLayout(LayoutKind.Sequential)]
    public struct fa_keylist
    {
        public Int32 kl_nkeys;                                  
        public UInt32 kl_reserve;                              
        [MarshalAs(UnmanagedType.ByValArray)]
        public fa_keydesc[] kl_keys;    
    }
    [STAThread]
    [DllImport("F4AGFCFA.dll", EntryPoint = "cobfa_open", CallingConvention = CallingConvention.StdCall)]
    public static extern Int32 cobfa_open(
                        string fileName,
                        Int32 openFlags,
                        ref fa_keylist keyList,
                        Int32 recordLength);
对函数的调用编码为:

handle = cobfa_open(filename, fileFlags, ref keyList, 80);
顺便说一下,我已经尝试了许多不同的编组选项。我收到的当前错误是访问冲突(尝试读取或写入受保护内存)


如果您有任何建议,我们将不胜感激。

您需要指定阵列的大小。假设C中的
FA\u npart
为128,则可以执行以下操作:

[StructLayout(LayoutKind.Sequential)]
public struct fa_keydesc
{
    public Int32 k_flags;                            
    public Int32 k_nparts;                                
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
    public fa_keypart[] kparts;
};

UnmanagedType.ByValArray
也仅适用于
SizeConst
集。

您需要指定数组的大小。假设C中的
FA\u npart
为128,则可以执行以下操作:

[StructLayout(LayoutKind.Sequential)]
public struct fa_keydesc
{
    public Int32 k_flags;                            
    public Int32 k_nparts;                                
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
    public fa_keypart[] kparts;
};

UnmanagedType.ByValArray
也仅适用于
SizeConst
集。

不幸地尝试了此问题和相同的问题,因此上面的答案似乎没有帮助。我已经尝试过这种方法。是否有人知道Visual Studio中是否有任何高级调试技术可用于尝试确定C#实际输出的是什么,并试图将其交给一个没有可用源代码或调试信息的非托管.DLL?不幸的是,尝试了此问题和相同的问题,因此上面的答案似乎没有帮助。我已经尝试过这种方法。有人知道Visual Studio中是否有任何高级调试技术可用于尝试确定C#实际输出的内容,并尝试将其交给一个没有可用源代码或调试信息的非托管.DLL吗?您需要将fa#keydesc声明为类以获取指针数组。您需要声明fa_keydesc作为一个类来获取指针数组。