编组c#class到c ++结构的麻烦

时间:2014-05-24 11:50:15

标签: c# c++ pinvoke

我有C ++结构

struct DressKey
{
int         keyId;                  
GENDER      gender;                 
DRESS_CLASS dressClass;             
unsigned int descriptor[KEY_SIZE];
float       confidence;             
short       keyLength;              
short       metric;                 

DressKey():
    keyId(0),
    gender(GENDER_UNDEFINED),
    dressClass(CLASS_UNDEFINED),
    confidence(0.0f),
    keyLength(KEY_SIZE),
    metric(0)
{
    descriptor[0] = 0;
}

};

GENDER和DRESS_CLASS的类型是枚举

我尝试在方法中传递它:

virtual ERROR_CODE ExtractDressKey(
    const unsigned char *frame,
    int width,
    int height,
    int lineLength,
    int format,
    DressKey *dressKey);

我已经用这种方式在c#中包装了这个方法和结构:

[DllImport("DSE.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint = "?ExtractDressKey@DSE@dse@@UEAA?AW4ERROR_CODE@2@PEBEHHHHPEAUDressKey@2@@Z")]
private static extern ERROR_CODE ExtractDressKey(IntPtr self, IntPtr frame, int width, int height, int lineLength, int format, ref DressKey dressKey);


[StructLayout(LayoutKind.Sequential)]
public class DressKey
{

    public const int KEY_SIZE = 5768;
    public int keyId;                   //!< serialization key id
    public GENDER gender;                   //!< gender
    public DRESS_CLASS dressClass;              //!< dress category
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = KEY_SIZE)]
    public uint[] descriptor = new uint[KEY_SIZE];  //!< comparable part
    public double confidence;               //!< key confidence
    public short keyLength;             //!< actual numer of elements in descriptor
    public short metric;                    //!< ID of a metric revision
}

我收到了AccessViolationException。包装器有什么问题?

UPD

用法:

var imgPath = @"C:\1.jpg";

            using (var dse = new DSE())
            {
                using (var img = CV.LoadImageM(imgPath, LoadImageFlags.AnyColor))
                {
                    var subImg =  img;
                    using (subImg)
                    {
                        var dk = new DressKey();
                        var type = subImg.Channels == 1 ? 0 : 1;
                        var res = dse.ExtractDressKey(subImg.Data, subImg.Cols, subImg.Rows, subImg.Cols, type, ref dk);

                        if (res == ERROR_CODE.ERROR_OK)
                           Console.WriteLine("id={0}&key={1}", 123, JsonConvert.SerializeObject(dk));
                        else
                        {
                           Console.WriteLine( res.ToString());
                        }
                    }
                }

            }

1 个答案:

答案 0 :(得分:1)

您不能指望p / invoke C ++实例方法。 P / invoke用于调用非成员函数。您需要执行以下操作之一:

  1. 将C ++库包装在混合模式C ++ / CLI程序集中,并让C#代码将其作为托管引用使用。
  2. 使用COM公开C ++库。
  3. 将C ++库包装在C样式的过程接口中,并使用p / invoke访问它。