我有这样的结构
#define MAX_NAME_LENGTH 40
typedef struct _tagMYPERSON
{
WCHAR FName[MAX_NAME_LENGTH];
WCHAR LName[MAX_NAME_LENGTH];
int Age;
double Salary;
} MYPERSON;
然后我在DLL中具有这样的功能隐藏复制代码
extern "C" MARSHALDLL_API void _stdcall ModifyPersonStructArray(int nCount, MYPERSON * pPersonArr)
{
for ( int nI = 0; nI < nCount; nI++ )
{
wcscat_s(pPersonArr[nI].FName, MAX_NAME_LENGTH, L"-Modified");
wcscat_s(pPersonArr[nI].LName, MAX_NAME_LENGTH, L"-Modified");
pPersonArr[nI].Age = pPersonArr[nI].Age+ 5;
pPersonArr[nI].Salary = pPersonArr[nI].Salary + 1000 ;
}
}
这就是我的称呼。
int nCount = 4;
MYPERSON* prsnArr = new MYPERSON [nCount];
CString strTmp;
m_lstOutput.ResetContent ();
for (int nI=0; nI<nCount ; nI++)
{
strTmp.Format(_T("First Name %d"), nI+1);
StringCchCopyW(prsnArr[nI].FName, MAX_NAME_LENGTH, strTmp);
strTmp.Format(_T("Last Name %d"), nI+1);
StringCchCopyW(prsnArr[nI].LName, MAX_NAME_LENGTH, strTmp);
prsnArr [nI].Age = 20 + (nI+ 1)*2 ;
prsnArr [nI].Salary = 20000 + (nI+ 1) * 1000;
strTmp.Format(_T("Person %d=[(%s %s, Age=[%d], Salary=[%.2lf])]"), nI, prsnArr [nI].FName, prsnArr [nI].LName, prsnArr [nI].Age, prsnArr [nI].Salary);
m_lstOutput.AddString (strTmp);
}
ModifyPersonStructArray(nCount, prsnArr );
m_lstOutput.AddString(_T("After Call ==>"));
for (int nI=0; nI<nCount ; nI++)
{
strTmp.Format(_T("Person %d=[(%s %s, Age=[%d], Salary=[%.2lf])]"), nI, prsnArr [nI].FName, prsnArr [nI].LName, prsnArr [nI].Age, prsnArr [nI].Salary);
m_lstOutput.AddString (strTmp);
}
注意:m_lstOutput是MFC对话框中的控制变量(ListBox)。
当我在调试模式下运行时,我收到这样的错误消息,
Windows已在MFCClient.exe中触发断点。这可能是由于堆损坏所致,这表明MFCClient.exe或其已加载的任何DLL中都有错误。这也可能是由于用户在MFCClient.exe具有焦点时按下了F12。输出窗口可能包含更多诊断信息。
我在这里做错了什么?
我尝试过的事情:
我在Dialog类本身中转移了DLL函数。喜欢。
void CMFCClientDlg::ModifyPersonStructArray(int nCount, MYPERSON * pPersonArr)
{
for ( int nI = 0; nI < nCount; nI++ )
{
wcscat_s(pPersonArr[nI].FName, MAX_NAME_LENGTH, L"-Modified");
wcscat_s(pPersonArr[nI].LName, MAX_NAME_LENGTH, L"-Modified");
pPersonArr[nI].Age = pPersonArr[nI].Age+ 5;
pPersonArr[nI].Salary = pPersonArr[nI].Salary + 1000 ;
}
}
而且我没有问题。有效。
extern "C" __stdcall
的调用方法将在原始函数名称中添加一些参数符号。函数名称将像“ _ModifyPersonStructArray@8
”一样导出,取决于不同的编译器。
#define MAX_NAME_LENGTH 40
typedef struct _tagMYPERSON
{
WCHAR FName[MAX_NAME_LENGTH];
WCHAR LName[MAX_NAME_LENGTH];
int Age;
double Salary;
} MYPERSON;
extern "C" void __declspec(dllexport) __stdcall ModifyPersonStructArray(int nCount, MYPERSON * pPersonArr)
{
for (int nI = 0; nI < nCount; nI++)
{
wcscat_s(pPersonArr[nI].FName, MAX_NAME_LENGTH, L"-Modified");
wcscat_s(pPersonArr[nI].LName, MAX_NAME_LENGTH, L"-Modified");
pPersonArr[nI].Age = pPersonArr[nI].Age + 5;
pPersonArr[nI].Salary = pPersonArr[nI].Salary + 1000;
}
}
extern "C" BOOL __declspec(dllexport) func(int i);
BOOL func(int i)
{
printf("in dll func");
return 1;
}
您可以打开“ VS xxx的开发人员命令提示符”,键入以下cmd来检查导出的函数名称:
dumpbin /exports xxx.dll
typedef void (__stdcall *ModifyPersonStructArray)(int nCount, MYPERSON* pPersonArr);
样本:
#define _AFXDLL
#include <iostream>
#include <afx.h>
#include <strsafe.h>
#define MAX_NAME_LENGTH 40
typedef struct _tagMYPERSON
{
WCHAR FName[MAX_NAME_LENGTH];
WCHAR LName[MAX_NAME_LENGTH];
int Age;
double Salary;
} MYPERSON;
typedef void (__stdcall*ModifyPersonStructArray)(int nCount, MYPERSON* pPersonArr);
int main()
{
int nCount = 4;
MYPERSON* prsnArr = new MYPERSON[nCount];
CString strTmp;
HMODULE h = LoadLibrary(L"DLL2.dll");
ModifyPersonStructArray fun = (ModifyPersonStructArray)GetProcAddress(h,"_ModifyPersonStructArray@8");
for (int nI = 0; nI < nCount; nI++)
{
strTmp.Format(_T("First Name %d"), nI + 1);
StringCchCopyW(prsnArr[nI].FName, MAX_NAME_LENGTH, strTmp);
strTmp.Format(_T("Last Name %d"), nI + 1);
StringCchCopyW(prsnArr[nI].LName, MAX_NAME_LENGTH, strTmp);
prsnArr[nI].Age = 20 + (nI + 1) * 2;
prsnArr[nI].Salary = 20000 + (nI + 1) * 1000;
strTmp.Format(_T("Person %d=[(%s %s, Age=[%d], Salary=[%.2lf])]"), nI, prsnArr[nI].FName, prsnArr[nI].LName, prsnArr[nI].Age, prsnArr[nI].Salary);
}
fun(nCount, prsnArr);
}
或者只是删除__stdcall
声明。(我更喜欢这样)