- 浏览: 134781 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
aa87963014:
很好,但是update/insert 是否加锁 。加锁对sel ...
数据库锁 -
RobustTm:
我的这种做法也可以添加A和B
但是换成更新就有问题
hibernate入门(十一):级联操作inversin属性 -
RobustTm:
这位仁兄可以提供一对多双向关联完整的代码不?
我碰到了问题,采 ...
hibernate入门(十一):级联操作inversin属性 -
cfeers:
markxing 写道谢谢分享。。。
不客气,呵呵。
struts2.0 struts.xml配置文件详解 -
markxing:
谢谢分享。。。
struts2.0 struts.xml配置文件详解
C/C++调用Delphi制作的dll时发现的一些问题 收藏
做了一个网络业务逻辑实体,是用C++编写的dll,内部有一个全局的业务实体,外部准备用Delphi编写的界面程序来控制并显示状态......
1. C++的dll中不能用C++风格的导出方式:_declspec(dllexport)来导出函数,要用C风格的导出方式:extern "C" _declspec(dllexport),否则Delphi在加载C++的dll时报错:无法定位函数xxxFun()于xxxDll.dll上。(这里假设只讨论这两种导出方式)不知道delphi能不能调用其他C风格的dll...?
例子:
C++中要这样声明函数,
extern "C" _declspec(dllexport) int Initialize();
Delphi中声明要这样,
Function Initialize():Integer; cdecl; external 'c_test.dll' name 'Initialize';
注意,这里的 cdecl 是必须的,其他的(如stdcall,pascal...)貌似都不行......似乎它是delphi调用c编写的dll的唯一合法标识,因为这由C++的dll中的_declspec方式决定了,然而在C++中为了能给delphi调用,又不允许使用其他的(如WINAPI,CALLBACK,PASCAL...)导出方式,所以就只能这样使用_declspec了。
但是,有人说过这样的对应方式:
C++的参数调用方式 对应的DELPHI的参数调用方式
_declspec cdecl
WINAPI,CALLBACK stdcall
PASCAL pascal
附注:C++中的char *对应PASCAL中的PChar。
不是没有试过,只是没有调试成功过,所以最终还是用的以上方式,即在C++中用extern "C" _declspec(dllexport)声明函数,在Delphi中用cdecl声明函数,然后Delphi应用程序调用C++的dll。
2.在1中的调用为主动调用,即delphi主动调用C++的dll,倘若反过来,用C++或者C来调用Delphi的函数,问题有些不一致了,这里又要分为两种情形:
1)C++的应用程序,调用Delphi编写的dll。
2)Delphi在调用C++的dll时,传递函数指针给dll,在dll内部根据业务逻辑,回叫这个delphi函数。
(其实1)和2)的情形似乎都一样...)
因为pascal和c是两种不同风格的语言,它们的参数列表的出栈进栈方式不一样,所以,最容易出问题的就是函数的参数列表了。不光参数列表中参数顺序会乱,而且乱得没有规律可循,当只涉及到一个整型参数时,没有问题,正常调用,但是,这只是碰巧没有问题而已......
首先,对于C++应用程序调用Delphi编写的dll,
可以这样,在C++程序里,
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
typedef int(*myFun)(int arg1,int arg2,int arg3,int arg4);
int main(int argi,char* argv[])
{
HINSTANCE hDll;
hDll=LoadLibrary("delphi_dll.dll");
if (hDll!=NULL)
{
myFun fun;
fun=(myFun)GetProcAddress(hDll, "c_exe_test2");
if(fun!=NULL)
{
for(int i=0;i<5;i++)
{
printf("%d,%d,%d,%d\n",i,i+1,i+2,i+3);
fun(i,i+1,i+2,i+3);
}
}
FreeLibrary(hDll);
}
system("pause");
return 0;
}
然后在Delphi编写的dl内部,
library delphi_dll;
uses
SysUtils,
Classes,
Dialogs;
Function c_exe_test2(arg1,arg2,arg3,arg4: Integer): Integer; cdecl;
Begin
ShowMessage(
'arg1='+IntToStr(arg1)+' '+
'arg2='+IntToStr(arg2)+' '+
'arg3='+IntToStr(arg3)+' '+
'arg4='+IntToStr(arg4));
end;
exports
c_exe_test2 index 1;
begin
//todo...dll被加载时执行一次...
end.
注意了,在Delphi的dll内部,cdecl 声明是必不可少的,否则就会出现参数列表的混乱...
接下来,就去调试下C++的dll内部回叫Delphi程序的函数指针,再次检查参数列表是否正确,
在C++的dll中,
//--------------------------------------------------------------------------------
//xxx.h:
typedef int(*OnTest)(int arg1,int arg2,int arg3,int arg4);
extern "C" _declspec(dllexport) int setcb_on_test(OnTest pFun);
//--------------------------------------------------------------------------------
//xxx.cpp:
#include <Windows.h>
static OnTest CallBackOnTest = NULL;
extern "C" _declspec(dllexport) int setcb_on_test(OnTest pFun)
{
CallBackOnTest=pFun;
return 0;
}
void fun(void* arg)
{
int i=0,arg1=1,arg2=2,arg3=3,arg4=4;
while(1)
{
i++;
if(i%5==0)
if(CallBackOnTest)
{
CallBackOnTest(arg1,arg2,arg3,arg4);
arg1++;arg2++;arg3++;arg4++
}
Sleep(1000);
if(i>=100) break;
}
}
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved )
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
HANDLE threadHandle;
DWORD threadID;
threadHandle = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)fun,
NULL,
0,
&threadID);
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
在Delphi应用程序中,
unit UnitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Dialogs;
Type
TObjMain = class(TObject)
private
{ Private declarations }
Public
{ Public declarations }
Constructor Create(owner: TObject);
Destructor Free();
end;
var
myObj: TObjMain ;
type
TOnTest = Function(arg1,arg2,arg3,arg4: Integer): Integer; cdecl;
Function SetCB_OnTest(pFun: TOnTest): Integer; cdecl; external 'c_test.dll' name 'setcb_on_test';
Function OnTest(arg1,arg2,arg3,arg4: Integer): Integer; cdecl;
implementation
{$R *.pas}
Function OnTest(arg1,arg2,arg3,arg4: Integer): Integer;
begin
ShowMessage(
'arg1='+IntToStr(arg1)+' '+
'arg2='+IntToStr(arg2)+' '+
'arg3='+IntToStr(arg3)+' '+
'arg4='+IntToStr(arg4 );
result:=0;
end;
constructor myObj.Create(owner: TObject);
begin
inherited;
//todo...
SetCB_OnTest(OnTest);
end;
destructor myObj.Free();
begin
//todo...
inherited;
end;
再在工程文档中,
program d_test;
uses
UnitMain in 'UnitMain.pas' {myObj};
{$R *.res}
Begin
Application.Initialize;
myObj:=TObjMain.Create(Application);
Application.Run;
end.
发表评论
-
使用Delphi编写自动关闭Windows信使服务窗体程序
2013-02-18 15:27 785使用Delphi编写自动关闭Windows信使服务窗体程序 ... -
一种自动关闭对话框的简单方法
2013-02-18 15:26 623{***************************** ... -
delphi VCL常用属性
2011-06-21 14:35 1009delphi VCL常用属性 属性 ... -
delphi VCL常用方法
2011-06-21 14:34 1087begindrag ... -
Delphi中安装第三方控件
2011-06-05 21:03 931基本安装 1、对于单个控件,Componet--& ... -
Delphi图表控件TChart使用(收藏)
2011-05-16 12:01 2073最近开发要使 用图表, ... -
delphi 双进程守护
2011-05-12 17:04 1324这是一个关于父亲与儿子的故事: 父亲的一生:①生一个儿子。如果 ... -
Win32全局钩子在Delphi下实现的关键技术
2011-05-12 17:02 1007<script type="text/ja ... -
获取 CPU 使用率
2011-05-12 16:53 1265获取 CPU 使用率 unit Unit1; int ... -
AcmIn/AcmOut 语音采集
2011-05-12 16:53 997AcmIn/AcmOut 语音采集 unit Unit ... -
哥德巴赫猜想的delphi7程序代码
2011-05-12 16:52 764unit Unit1; interface ... -
Delphi ActionList详解
2011-05-12 16:51 836一个友好的用户界面,必须具有下拉菜单,弹出菜单,工具条和快捷键 ... -
利用远程线程注入DLL (DELPHI版)
2011-05-12 16:50 2264研究外挂3个多月了~ ... -
Delphi 调用控件的过程,初学者都想知道
2011-05-12 16:46 1263假设有过程: procedure TForm1.Button ... -
格式化数字字符串输出的一个小技巧
2011-05-12 16:42 743我这里分别以VC和Delphi举例: 比如想生成 00000 ... -
Delphi连接数据库通用方法
2011-05-04 17:17 2234DELPHI 连接数据库是个头痛的问题,现在我写了个通用方法, ... -
通俗讲解对象和接口(转贴)
2011-05-04 15:19 670最近,还是看到很多人 ... -
用两种方法快速简单的实现窗口淡入淡出 收藏
2011-05-04 15:16 779用两种方法快速简单的实现窗口淡入淡出 收藏 在应用程序中引 ... -
如何让控件在编译时,自动添加所需的单元
2011-05-04 14:47 669在开发控件的时候,常会类似碰到这样的情况:我某个方法或事件的参 ... -
DELPHI基础开发技巧
2011-05-03 11:25 839DELPHI基础开发技巧◇[DELPHI]网络邻居复制文件us ...
相关推荐
本文档说明了Delphi调用c++ dll的一些技术细节,讲述了如何调用c++的动态链接库接口技术
jni调用c++ delphi中的dll.
C++、VB、DELPHI调用DLL的小例子。DLL是用VC++写的。同学在做毕业设计时要求调用DLL,我就顺便把VB和DELPHI的也做上了
将sqlite的简单功能(execsql, query)封闭到dll中.可通过标准c函数接口操作. 以前写过一个简单的类.可以供c/c++调用. 现在写了一个dll可以供其它语言环境使用. 代码中预留了其它数据库接口的扩展性.
C++、VB、DELPHI调用DLL的小例子。DLL是用VC++写的。同学在做毕业设计时要求调用DLL,我就顺便把VB和DELPHI的也做上了。 继加了JAVA调用DLL后,空闲的时候又加了个C#调用的例子。根据以前下载过的朋友的要求,...
在VC中的DLL类导出以后完全是可以被delphi调用的. 源码中有详细介绍和说明文档.
Silverlight使用WebService调用C++,Delphi编写的DLL文件实例源码,
这段时间调用C++的DLL带有CALLBACK回调参数的方法,经过一端时间研究,已经成功调用了,拿出去同大家分享一下
把C++中的类封装成DLL,导出此类的对象给Delphi层调用。区别于以往的导出函数的方式,此示例是导出对象。
专家包以 DLL 的方式集成到 IDE 中,包括一组以菜单和快捷键调用的工具、扩展的属性编辑器、组件编辑器及代码、窗体资源模板等。当前支持的编译器有 Borland Delphi 5/6/7, C++Builder 5/6 和 BDS 2005/2006、RAD ...
之前发布过C++、VB、DELPHI调用DLL的。今天新增JAVA调用DLL的。用的是Jawin库,省得自己另外再写东西了。
本实例介绍用Delphi调用C++写的dll的一个简单的例子
32bit程序调用64bit dll 的解决办法 32bit程序不能直接调用64bit的dll,我们采用COM进程外组件的方式来实现间接调用。
Delphi中制作DLL •一 Dll的制作一般分为以下几步: 1 在一个DLL工程里写一个过程或函数 2 写一个Exports关键字,在其下写过程的名称。不用写参数和调用后缀。 二参数传递 1 参数类型最好与window C++的参数类型一致...
基本上覆盖了目前主流的开发语言,DLL使用C++编写,演示了VB、C++、DELPHI、JAVA、C#、汇编、易语言调用这个DLL的方法。有些语言我提供了静态和动态2种调用方法。没有写的恕我孤陋寡闻,如果谁知道请联系我QQ:...
delphi封装的回调函数DLL,为了自动触发事件
delphi的RSA的加解密,delphi生成dll,然后demo调用该dll进行加解密
点量Http、FTP多线程断点续传下载...点量Http、FTP下载内核源码使用高效的c++代码编写,提供标准的动态链接库(DLL),可供C/C++、Delphi、C#、Java、VB等语言和各常用开发环境调用,让您完全像调用系统API一样的调用。
这两年,我在VBA应用方面一直有几大痛点: ...本DLL库可以被C++、VB6、Delphi、VBA等多种语言调用(接口提供VBA示例,其它语言自己写。)。支持32位和64位操作系统。 运行环境:需要.net Framework 4.0或以上,支持XP。
纯商业代码,可以快速应用集成到 工程...代码接口为纯 C 或 c++ 或 delphi 未使用任何开源库或者.NET库 可以导出标准C函数DLL供任何语言调用 也可以给代码集成到自己工程当中。 ////////////////////////////////////