2012-03-20 56 views
2

我很难尝试编组我在C#程序中定义的结构,这是调用非托管C .DLL文件所必需的我无权访问源代码对于。一个示例非托管C程序C程序可以调用这个.DLL没有问题。下面的问题结构是fa_keylist。有包含在我有结构问题的多个子结构:问题编组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;  
    } 

的的DllImport实际呼叫的签名定义为:

[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); 

我已经尝试了一些不同的编组选项的方式。我收到的当前错误是访问冲突(尝试读取或写入受保护的内存)。

任何建议将不胜感激。

+0

您需要将fa_keydesc声明为一个类来获取指针数组。 – 2012-03-21 00:28:48

回答

0

您需要指定数组的大小。假设FA_NPARTS在C是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.ByValArraySizeConst设置也有效。

+0

不幸的尝试了这个和同样的问题 – user1281847 2012-03-20 22:20:37

+0

所以上面的答案似乎没有帮助。我已经尝试过这种方法。有谁知道在Visual Studio中是否有任何高级调试技术可用来确定C#实际上正在输出什么,并试图将其转移到没有源代码或调试信息的非托管.DLL? – user1281847 2012-03-21 13:48:58