背景:
将原有的SoftwareDog.dll,移植到C#程序中,实现其原有的授权加密功能。
问题:
运行时,总是在Create的时候遇到问题。查了资料说修改为X64平台也不行
C#源码
using System;
using System.Runtime.InteropServices;
namespace ConsoleApp2
{
class Program
{
private static IntPtr myClassInstance;
[DllImport("DLLDOGCHECK.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateMyClass();
[DllImport("DLLDOGCHECK.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void DeleteMyClass(IntPtr obj);
[DllImport("DLLDOGCHECK.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int CallInitDog(IntPtr obj);
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.WriteLine("start");
myClassInstance = CreateMyClass();
Console.WriteLine("CreateMyClass");
int nRet = 0;
nRet = CallInitDog(myClassInstance);
Console.WriteLine($"CallInitDog={nRet}");
}
}
}
C++ 头文件
```c++
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLLDOGCHECK_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// DLLDOGCHECK_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef DLLDOGCHECK_EXPORTS
#define DLLDOGCHECK_API __declspec(dllexport)
#else
#define DLLDOGCHECK_API __declspec(dllimport)
#endif
#include <string>
#include <atlstr.h>
// 此类是从 dll 导出的
typedef int (*HS_InitSoftwareDog)(char* _pstrDogID, char* _pstrExpireTime, char* _pstrAuthority, char* _pstrDeveloperNo);
typedef int (*HS_GetDogNowTime)(char* _pstrNowTime);
typedef int (*HS_GetDeviceNo)(char* _pstrLocateNo, char* _pstrDogDeviceNo);
class DLLDOGCHECK_API CDllDogCheck {
// TODO: 在此处添加方法。
public:
CDllDogCheck(void);
BOOL InitDog(CString& strError);
BOOL InitDogSub(CString& strError);
void GetExepath(TCHAR* pPath);
BOOL LoadLib(void);
void FreeLib(void);
UINT CheckDogThread();
HS_InitSoftwareDog m_pInitSoftwareDog;
HS_GetDogNowTime m_pGetDogNowTime;
HS_GetDeviceNo m_pGetDeviceNo;
HMODULE m_hModule;
CString m_strDogID; // 狗ID
CString m_strExpireTime; // 到期时间
CString m_strAuthority; // 权限
CString m_strDogErrorMsg;
BOOL m_bExit;
};
extern "C" {
extern DLLDOGCHECK_API int nDllDogCheck;
DLLDOGCHECK_API int fnDllDogCheck(void);
DLLDOGCHECK_API int CallInitDog(CDllDogCheck* Obj);
DLLDOGCHECK_API CDllDogCheck* CreateMyClass();
DLLDOGCHECK_API void DeleteMyClass(CDllDogCheck* Obj);
}
C++ .CPP
```c++
// DllDogCheck.cpp : 定义 DLL 的导出函数。
//
#include "framework.h"
#include "DllDogCheck.h"
// 这是导出变量的一个示例
DLLDOGCHECK_API int nDllDogCheck=0;
// 这是导出函数的一个示例。
DLLDOGCHECK_API int fnDllDogCheck(void)
{
return 0;
}
// 这是已导出类的构造函数。
CDllDogCheck::CDllDogCheck()
{
return;
}
BOOL CDllDogCheck::InitDog(CString& strError)
{
if (!InitDogSub(strError))
{
m_strDogErrorMsg = strError;
}
if (!m_strDogErrorMsg.IsEmpty())
{
strError = m_strDogErrorMsg;
return FALSE;
}
return TRUE;
}
BOOL CDllDogCheck::InitDogSub(CString& strError)
{
if (LoadLib() == NULL)
{
strError = _T("Fail to Load SoftWareDog.dll");
return FALSE;
}
char pstrDogID[100] = { 0 };
char pstrExpireTime[100] = { 0 };
char pstrAuthority[100] = { 0 };
char pstrDescription[100] = { 0 };
char pstrDevelopNo[100] = { 0 };
char pstrDogDevelopNo[100] = { 0 };
int nItem = m_pInitSoftwareDog(pstrDogID, pstrExpireTime, pstrAuthority, pstrDescription);
if (nItem != 0)
{
strError = _T("加密狗错误");
return FALSE;
}
nItem = m_pGetDeviceNo(pstrDevelopNo, pstrDogDevelopNo);
if (nItem != 0)
{
strError = _T("加密狗错误");
return FALSE;
}
CString strDogDevelopNo(pstrDogDevelopNo);
if (strDogDevelopNo.Find(_T("-------")) > -1)
{
strError = _T("加密狗错误");
return FALSE;
}
CString strDescription(pstrDescription);
strDescription.Trim();
if (strDescription != _T("AAAA"))
{
strError = _T("加密狗错误");
return FALSE;
}
return TRUE;
}
void CDllDogCheck::GetExepath(TCHAR* pPath) //获取执行目录
{
TCHAR pExePath[256];
::memset(pExePath, 0, sizeof(TCHAR) * 256);
GetModuleFileName(NULL, pExePath, 256);
TCHAR* pEnd = _tcsrchr(pExePath, '\\');
*(pEnd + 1) = NULL;
if (pPath)
{
_tcscpy_s(pPath, 256, pExePath);
}
return;
}
BOOL CDllDogCheck::LoadLib(void)
{
TCHAR pszPath[1024] = { 0 };
GetExepath(pszPath);
CString strPathTemp(pszPath);
CString strMarkLib;
strMarkLib.Format(_T("%sSoftWareDog.dll"), strPathTemp);
m_hModule = LoadLibrary(strMarkLib);
int nErr = GetLastError();
if (m_hModule == NULL)
return FALSE;
m_pInitSoftwareDog = (HS_InitSoftwareDog)GetProcAddress(m_hModule, (LPSTR)1);
m_pGetDogNowTime = (HS_GetDogNowTime)GetProcAddress(m_hModule, (LPSTR)2);
m_pGetDeviceNo = (HS_GetDeviceNo)GetProcAddress(m_hModule, (LPSTR)3);
return m_pInitSoftwareDog && m_pGetDogNowTime && m_pGetDeviceNo;
}
void CDllDogCheck::FreeLib(void)
{
if (m_hModule)
{
FreeLibrary(m_hModule);
}
m_hModule = NULL;
m_pInitSoftwareDog = NULL;
m_pGetDogNowTime = NULL;
m_pGetDeviceNo = NULL;
}
HANDLE hDogSts = ::CreateEvent(NULL, TRUE, FALSE, NULL);
UINT CDllDogCheck::CheckDogThread()
{
CString strError;
if (!InitDogSub(strError))
{
m_strDogErrorMsg = strError;
}
SetEvent(hDogSts);
return 0;
}
DLLDOGCHECK_API CDllDogCheck* CreateMyClass()
{
return new CDllDogCheck();
}
DLLDOGCHECK_API void DeleteMyClass(CDllDogCheck* Obj)
{
delete Obj;
}
DLLDOGCHECK_API int CallInitDog(CDllDogCheck* Obj)
{
CString strError;
if (Obj->InitDog(strError))
{
return 0;
}
else
{
return 1;
}
}
dllmain.cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "framework.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}