当前位置: 代码迷 >> C# >> c#中调用mfc dll有关问题
  详细解决方案

c#中调用mfc dll有关问题

热度:63   发布时间:2016-05-05 02:33:45.0
c#中调用mfc dll问题
有一个mfc写的dll需要在c#中调用,不知道该如何调用。
用普通的方式提示加载不到,改如何解决?

[DllImport("DataCRC.ll", EntryPoint = "GetCRCValue")]
        public static extern long GetCRCValue(byte[] packdata);


下面是dll的内容
.h
#if !defined(_DataCRC)
#define _DataCRC
#if !defined(_CRC_DataCRC_Define_)
#define _CRC_DataCRC_Define_

//函数说明:用于获取数据的CRC值
//参数说明:
//baData :需要获取CRC值的数据
//返回值说明:
//返回数据的CRC值
ULONG_PTR AFX_API_EXPORT AFXAPI GetCRCValue(CByteArray &baData);
#endif

#endif

.cpp


#include "stdafx.h"
#include <afxdllx.h>
#ifdef _MANAGED
#error Please read instructions in DataCRC.cpp to compile with /clr
// If you want to add /clr to your project you must do the following:
// 1. Remove the above include for afxdllx.h
// 2. Add a .cpp file to your project that does not have /clr thrown and has
//    Precompiled headers disabled, with the following text:
// #include <afxwin.h>
// #include <afxdllx.h>
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


static AFX_EXTENSION_MODULE DataCRCDLL = { NULL, NULL };

#ifdef _MANAGED
#pragma managed(push, off)
#endif

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);

if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("DataCRC.DLL Initializing!\n");

// Extension DLL one-time initialization
if (!AfxInitExtensionModule(DataCRCDLL, hInstance))
return 0;

// Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
//  an MFC Regular DLL (such as an ActiveX Control)
//  instead of an MFC application, then you will want to
//  remove this line from DllMain and put it in a separate
//  function exported from this Extension DLL.  The Regular DLL
//  that uses this Extension DLL should then explicitly call that
//  function to initialize this Extension DLL.  Otherwise,
//  the CDynLinkLibrary object will not be attached to the
//  Regular DLL's resource chain, and serious problems will
//  result.

new CDynLinkLibrary(DataCRCDLL);

}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("DataCRC.DLL Terminating!\n");

// Terminate the library before destructors are called
AfxTermExtensionModule(DataCRCDLL);
}
return 1;   // ok
}

#ifdef _MANAGED
#pragma managed(pop)
#endif


#if !defined(_CRC_DataCRC_)
#define _CRC_DataCRC_

ULONG_PTR AFX_API_EXPORT AFXAPI GetCRCValue(CByteArray &baData)
{
ULONG_PTR Crc32Table[4] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L
};
ULONG_PTR  crc(0xFFFFFFFF);
INT_PTR DataLen,i;
DataLen=baData.GetSize();
for(i=0;i<DataLen;i++)
crc=(crc>>8)^Crc32Table[(crc&0xFF)^baData.GetAt(i)];
return crc^0xFFFFFFFF;
}

#endif


------解决思路----------------------
C#不能使用MFC的CByteArray。

因为CByteArray不是基础数据类型,C#不知道它的具体内存布局,无法正确封送。
具体的说,目前CByteArray布局(32位)
4个字节的虚函数表指针(vtable)
4个字节的数据指针,指向byte数组。
4个字节的长度,
4个字节的容量,
4个字节的增量。

而C#默认把byte[]封送为“4个字节的数据指针",跟*CByteArray的布局完全不同,你传byte[]没有引起程序崩溃就算运气好的了。


解决方法:
不使用MFC的类,而是用基础类型,比如
ULONG_PTR AFX_API_EXPORT AFXAPI GetCRCValue(LPBYTE pData, int dataLength)
------解决思路----------------------
ULONG_PTR===uint

如果是4楼的方法签名,转出来应该是

public static extern  uint GetCRCValue(ref byte pData, int dataLength) ;
  相关解决方案