有一个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) ;