delphi调用VC写的一个DLL,不行为什么呀(100分)

  • 主题发起人 主题发起人 zytzjx
  • 开始时间 开始时间
Z

zytzjx

Unregistered / Unconfirmed
GUEST, unregistred user!
在vc中是这样就可以
__declspec(dllimport) BYTE MacAccess(BYTE mode,BYTE *mac,BYTE portnum);
__declspec(dllimport) short GetInteralErrorCode();
void CMACLTesterDlg::OnRead()
{
BYTE ret = 0;
BYTE mac[6];
ret = MacAccess(0,mac,1);
if(ret)
{
CString error;
error.Format("Error Num %d",ret);
AfxMessageBox(error);
short code = GetInteralErrorCode();
error.Format("Internal error code 0x%04X",code);
AfxMessageBox(error);
}
else
{
CString error;
error.Format("Mac Address is 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X ",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
AfxMessageBox(error);
}
}
这是完全正确的。
unit DllInput;
interface
uses Windows;
function GetInteralErrorCode() : WORD;cdecl;
function MacAccess(mode : BYTE;
mac : PBYTE;
portnum : BYTE) : BYTE;
cdecl;
const
WriteMac = 'MACL.dll';
implementation
function GetInteralErrorCode;
external WriteMac name 'GetInteralErrorCode';
function MacAccess;external WriteMac name 'MacAccess';
end.
这是这样写的,我也用了Stdcall, pacasel 试了,都不行了,出错是在运行时,出现
无法定位程序输入点MacAccess于动态链接库MACL.dll
可是就是这个动态库中的呀,路径也是对的
 
无法定位程序输入点MacAccess于动态链接库MACL.dll
macl.dll中没有macaccess 函数
 
怎么可能呢,我用了VC中的一个工具看了,是
?GetInteralErrorCode@@YAFXZ
?MacAccess@@YAEEPAEE@Z
是这样的两个
有的,请回答呀,如果没有,VC那样写为什么行呀。
 
function GetInteralErrorCode() : WORD;stdcall;
function MacAccess(mode : BYTE;
mac : PBYTE;
portnum : BYTE) : BYTE;
stdcall;
这样行不行???
 
register Left-to-right Routine Yes
pascal Left-to-right Routine No
cdecl Right-to-left Caller No
stdcall Right-to-left Routine No
safecall Right-to-left Routine No
这些我都用过了,都不行的,怎么回事呀
 

最好用 __cdecl__ 定义,加上 ??? "C" <- 这个我忘了交傻了但是后面有个 "C" 这个,把需要让Delphi访问的函数用 { 给 扩起来,或者 请书写 import 输出声明文件。
好就没用C ,环境也没有,指能想起这么多,应该有帮助

 
翻了一下老程序。。。。。。。。。。。。。。。。。,关键处俺给你标出来了。
#include <windows.h>
char *pProc = "{call PutAccountMsg('%s','%s','%s',%d)}";
#include "YHTMHPHEAD.H"
#include "YHTMHPODBC.H"

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

#define dresultsize 128
/*v---------v 关键 */
extern "C" {
__declspec(dllexport)
/* v-----v 关键 */
int __cdecl iInitialize(struct SServiceParameter *p_psSP)
{
if(p_psSP)
{
p_psSP->iEnvSize = 0;
p_psSP->iCallParamSize = 0;
p_psSP->iCallResultSize = 0;
}
return 1;
}
__declspec(dllexport)
/* v-----v 关键 */
int __cdecl iRelease(struct SServiceParameter *p_psSP)
{
return 1;
}
/* 2000-10-17 04:35:09*/
__declspec(dllexport)
/* v-----v 关键 */
int __cdecl iCall(struct SServiceCall *p_psSC)
{
if(p_psSC)
{
if(p_psSC->p_pParam)
{
if(p_psSC->p_piRSize)
{
*p_psSC->p_piRSize = dresultsize;
}
if(p_psSC->p_pResult)
{
long lno;
struct sodbc so;
memset(p_psSC->p_pResult ,0 ,dresultsize);
if(iopenodbc(&amp;so ,"DRIVER=ORACLE ODBC DRIVER;UID=WZ_MEDICARE;DBQ=WZ_LINUX;SERVER=WZ_LINUX;PWD=xn2000"))
{
lno = igetlogno(&amp;so);
if(lno)
{
if(iexecproc(&amp;so ,p_psSC->p_pIp ,p_psSC->p_pUser ,p_psSC->p_pParam ,lno))
{
igetresult(&amp;so ,lno ,p_psSC->p_pResult ,dresultsize);
}
}
}
icloseodbc(&amp;so);
}
}
}
return 1;
}
}/* <<< 关键 与 extern "C" 对应 */
 
也就是说用了extern "C"写,就可以用delphi中的stdcall来调用吧,可是这个DLL是别人写的,我没有办法改了,他给的VC的例子也可以,我用到Delphi中就不行,怎么办呀
 
我在C++Builder中调用Vc写的dll是使用动态的方法写的,原来看过文章说静态调用会有问题。Delphi中实现应该差不多,可以参考一下。
//载入动态链接库
g_socket_handle = LoadLibrary("socket.dll");
//定义函数指针
bool (*lpStartServer)(char*);
//得到StartServer函数在内存中的位置
FARPROC lpFarProc = GetProcAddress(g_socket_handle,"StartServer");
lpStartServer=(bool(_cdecl *)(char*))lpFarProc;

//执行
return lpStartServer(Port);
这种方法是动态载入动态链接库,可以调用所有的函数,我觉得挺方便的。
 
建议Dll的Call 方式都写成stdcall
 
会不会你的系统中还有一个MACL.dll
 
动态加我没有试的,用STDCALL我早就试过了,系统中只有一个在当前目录下
 
那干脆用函数序号来引用试试
 
那干脆用函数序号来引用试试
这个我早试过,是可以的,但我不知道为什么用那些就不行,我在此是要求得为什么,不是要得到怎么做。
 
to zytzjx
笨呀,做个壳不就行了,你自己再做一个DLL里面调用他的DLL不就OK了,变通一下省下无数时间。
 

delphi调用VC的DLL时不用name,因为VC的DLL没有别名(也许VC里面可以有,但是没有定义,我不太清楚)!!
把别名去掉应该就可以了!!
 
后退
顶部