views:

231

answers:

4

I am trying to call a function in a unmanaged C++ dll.

It has this prototype:

  [DllImport("C:\\Program Files\\MySDK\\VSeries.dll", EntryPoint = "BII_Send_Index_Template_MT" )]
internal unsafe static extern Int32 BII_Send_Index_Template_MT(IntPtr pUnitHandle, ref BII_Template template, Int32 option, Boolean async);

  BII_Template template = new BII_Template();
  error_code = BII_Send_Index_Template_MT(pUnitHandle, ref template, option, false);

I is how I define the BII_Template struct in C#:

 public unsafe struct BII_Template {
public ulong id;    
public ulong employee_id;  
public ulong password; 

public byte sensor_version;  
public byte template_version; 
public fixed char name[16];   
public byte finger;  
public byte admin_level;  
public byte schedule;  
public byte security_thresh; 
public fixed byte noise_level[18];   
public byte corramb;
public byte reference_x;
public byte reference_y;
public fixed byte ihcore[3];   
public fixed byte ivcore[3]; 
public byte temp_xoffset;  
public byte temp_yoffset;  
public byte index;    
public fixed byte inphase[5500];

};

It build and when I run it the dll return error_code = "The record checksum is invalid."

I assume that I am using the ref keyword in a wrong way or the size of some of the elements in the struct is wrong.

----- EDIT ------------

Here is the struct in C++:

typedef struct {
unsigned long id;  
unsigned long employee_id; 
unsigned long password; 
unsigned char sensor_version;  
unsigned char template_version; 
char  name[16]; 
unsigned char finger;  
unsigned char admin_level;  
unsigned char schedule;   
unsigned char security_thresh; 
unsigned char noise_level[18]; 
unsigned char corramb ;   
unsigned char reference_x ;
unsigned char reference_y ;
unsigned char ihcore[NUM_CORE];
unsigned char ivcore[NUM_CORE]; 
unsigned char temp_xoffset;  
unsigned char temp_yoffset;  
unsigned char index;    
unsigned char inphase[PACKED_ARRAY_SIZE];

} BII_Template;

A: 

u need to use structlayout.sequal property on BII_Template, google it for details.

Benny
Thanks for quick answer. I tried it but still same error.
Nerds Rule
or you can use http://www.red-gate.com/products/PInvoke.net/index.htm to generate the struct signature automatically.
Benny
or this tool: http://blogs.microsoft.co.il/blogs/sasha/archive/2008/01/12/p-invoke-signature-generator.aspx
Benny
Sequential layout is the default for C# structs, so that changes nothing.
Mattias S
A: 

My standard answer: add a C++/CLI assembly to your C# project. Then the problem will solve itself.

danbystrom
A: 

'unsigned long' in C++ is NOT equal to ulong in C#.

Use uint instead.

logicnp
A: 

After testing a lot it seams that using fixed char ... does not give the same as [MashalAs...]. After making this change it worked.

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct BII_Template { public uint id; public uint employee_id; public uint password;

public byte sensor_version;
public byte template_version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] name;
public byte finger;

public byte admin_level;
public byte schedule;
public byte security_thresh;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)]
public byte[] noise_level;
public byte corramb;
public byte reference_x;
public byte reference_y;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] ihcore;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] ivcore;

public byte temp_xoffset;
public byte temp_yoffset;
public byte index;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5500)]
public byte[] inphase;

};

Nerds Rule