1

I've strange problem:

the MFC structure is

#define SENSOR_DESC_LEN   30
#define CAM_ID_LEN        20  
typedef struct
{
 unsigned int SensorType;
 char         Desc[SENSOR_DESC_LEN];
 unsigned int CommType;  // USB or TCP - COMM_TYPE
 float        FirmwareVersion;
 float        HardwareVersion;
 int          Width;
 int          Height;
 int          ActiveStartX;
 int          ActiveStartY;
 char         CameraID[CAM_ID_LEN];
 unsigned int pCam;
 char         Color;
} CAMERA_CAP_API; 

the corresponding C# structure is:

[StructLayout(LayoutKind.Sequential)]
  public struct CAMERA_CAP_API
  {
    public uint SensorType;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
    public byte[] Desc;
    public uint CommType;
    public float FirmwareVersion;
    public float HardwareVersion;
    public int Width;
    public int Height;
    public int ActiveStartX;
    public int ActiveStartY;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public byte[] CameraID;
    public uint pCam;
    public sbyte Color;
  } ;

it is correct - I can pass this structure through DLL using the following signature:

[System.Runtime.InteropServices.DllImport("Camelot.dll", EntryPoint = "CamGetCamCaps", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern int CamGetCamCaps(int nCamNum, ref CAMERA_CAP_API CameraCap);

The problem is in ActiveX. (MFC)

I make the parameter as VARIANT. And it shows as object in C# side. however trying to pass the same structure to object fails:

object c = new CAMERA_CAP_API();
Camera1.GetCamCaps(ref c);  // Camera1 is the ActiveX control

I get the following error: An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll

Additional information: Value does not fall within the expected range.

I've also tried:

IntPtr ptr = Marshal.AllocCoTaskMem(200);
GetNativeVariantForObject...
  • without success.

I get the same error.

What is the problem?

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
alex gil
  • 69
  • 1
  • 9
  • Isn't `GetCamCaps ()` accept two arguments, integer and structure reference, and you are passing only one? It looks like it according to your code snippets. –  Sep 28 '10 at 20:15
  • GetCamCaps accepts only 1 parameter (object type; VARIANT in MFC side). That function will call CamGetCamCaps inside ActiveX. – alex gil Sep 28 '10 at 20:48
  • Excluding that, you are passing C# object instead of a VARIANT. You have to convert your object into C# variant before passing. Take a look at `Marshall.GetNativeVariantForObject` - http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getnativevariantforobject.aspx –  Sep 28 '10 at 21:02
  • Do you know which variant type the ActiveX control expects? You can try wrapping the parameter in a VariantWrapper and see if it helps. – Mattias S Sep 29 '10 at 12:28
  • I've found a solution in p.297 of Adam Nathan book: .NET and COM: The Complete Interoperability Guide. VariantWrapper/GetNativeVariantForObject can't treat structures. the solution is far more complicated. – alex gil Oct 01 '10 at 21:03
  • you dont really say why you want to pass it as a VARIANT in the first place. if it works in your former example, why not just use that? passing VARIANTs around is a very expensive operation. some tips too - when defining equivalent structures in .NET it is a good idea to use int32, uint32 and so on rather than just int and uint. in this way you'll more likely match the c++ type. –  Jul 09 '11 at 12:18

0 Answers0