BCB调用VC++的DLL的问题?

shally5 2005-01-06 06:32:38
我在BCB中调用VC++的DLL,但是DLL中的函数是类与类函数,如何导出啊?
用如下方法只导出了函数,但是只要一计算就报错,显然还是要导出类才行啊!
int _stdcall (*abcd)(int,int);
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HINSTANCE hInst=NULL;
hInst = LoadLibrary("my.dll");
if(hInst)
{
abcd =(int (__stdcall*)(int,int)) GetProcAddress(hInst,"Calculate");
Edit3->Text=IntToStr(abcd(StrToInt(Edit1->Text),StrToInt(Edit2->Text)));
FreeLibrary(hInst);
}
}
...全文
697 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
zcchm 2005-01-08
  • 打赏
  • 举报
回复
学习
jishiping 2005-01-07
  • 打赏
  • 举报
回复
既然是公司内另外一个人写的,为什么那个人就不能提供源程序给你?难道这段代码是公司的机密,不能让其它人看到?否则就让他做成函数的格式(比如象我上面说的那样),这样你就可以调用了。
Thumb168 2005-01-07
  • 打赏
  • 举报
回复
如果这种情况,你要使用,最好你用VC做个标准DLL,或做个组件进行调用就行了.
yijiansong 2005-01-07
  • 打赏
  • 举报
回复
C++烂
shally5 2005-01-07
  • 打赏
  • 举报
回复
哎源程序不是我的,是别人的,他用MFC作成DLL,再用MFC调用就可以,
提供给其它人员使用,但是只有我用BCB,所以用不了啊!没办法啊,只有我用不了。
现在又一次发现用BCB的苦啊!

ssyfrank 2005-01-07
  • 打赏
  • 举报
回复
gz
RomanticProgrammer 2005-01-07
  • 打赏
  • 举报
回复
如果你不把 int GetNum();设为vitual,只能静太的方式调用这个函数,而无法实现动态调用!原因上面已经解释过了!
RomanticProgrammer 2005-01-07
  • 打赏
  • 举报
回复
还是关于动态调用dll中导出类的函数的方法:
因为dll是动态加载到进程空间的,因此在编译是无法确定函数的地址.但是大家都知道COM组件都是动态加载到内存的.但是我们却可以随心所欲的调用COM对象的成员函数,其实原因很简单,因为COM组件中的类的成员函数都是用虚函数.所以我们也可以模拟COM组件的方法,唯一的缺点是函数的性能要受到影响(因为需要查找vtable才能找到函数的入口地址)
如下:
class A
{
private:
int m_nNum;
public:
A();
A(int n);
virtual ~A();
virtual void SetNum(int n);
virtual int GetNum();
};
extern "C" __declspec(dllexport) A* CreateObjectofA1()
{
return new A();
}


//
typedef A* (*PFNCreateA1)();

PFNCreateA1 pfnCreateA1 =
(PFNCreateA1)GetProcAddress(hMod, TEXT("CreateObjectofA1"));

A* a = (pfnCreateA1)();
a->SetNum(1);
_tprintf(TEXT("Value of m_nNum in a is %d\n"),a->GetNum());

delete a;
RomanticProgrammer 2005-01-07
  • 打赏
  • 举报
回复
第二种方法:
RomanticProgrammer 2005-01-07
  • 打赏
  • 举报
回复
更正
Pfn classFunc =
func_cast<Pfn>(GetProcAddress(hInst,"ExpFunc "));
RomanticProgrammer 2005-01-07
  • 打赏
  • 举报
回复
更正:
可以动态调用导出类的成员函数.(如果是静态,则没有什么值得讨论的,用BCB的工具从新生成lib文件,加入到BCB的工程,然后加入头文件即可)
RomanticProgrammer 2005-01-07
  • 打赏
  • 举报
回复
//////////////////////////////////////////////////////////////////////////////////////

BCB可以使用VC++写dll的中的函数,类,以及类的成员函数.我保证,因为我做过!

如果你有这个dll的工程:
1:用Depends打开这个dll,看这个dll的导出函数和类名是否和.h文件的说明相同.如果不同.
1.1:用VC++打开这个工程,在工程中添加YourProjectName.def文件.在这个文件中强制命名导出函数. 比如 ExpFunc = _ExpFunc@12; 这个 _ExpFunc@12是你用depends看到的类的成员函数名.
1.2:编译.


可以只有动态调用导出类的成员函数.(如果是动态,则没有什么值得讨论的,用BCB的工具从新生成lib文件,加入到BCB的工程,然后加入头文件即可)
因为导出的成员函数是类成员函数类型,因此需要这样调用:
先写一个强制转换函数:之所以我们需要定义一个这样的函数就是为了在一般函数和类的成员函数之间进行转换;
template<class T1,T2>
T2 func_cast(T1 src)
{
union
{
T2 d;
T1 s;
} conver;

conver.s = src;
return conver.d;
}
假设导出类A有个void func(int) 类型的函数.

先定义类成员函数指针typedef void (A::*Pfn)(int); //如果你没见过A::*Pfn这种语法,建议你再蓄意一下你的C++

然后产生定义一个A的实例,A *a = new A;
//如果这个成员没有使用类的变量,你可以这样避免分配内存

//char pading[100];
A *a = new(pading)A;
你也可以这样
A *a = (A*)new char[100];

HINSTANCE hInst=NULL;
hInst = LoadLibrary("my.dll");
Pfn classFunc =
force_cast<Pfn>(GetProcAddress(hInst,
"ExpFunc "));
然后就可以这样调用了,同样,这是这里使用了比较晦涩的类成员函数指针的语法:
(a->*classFunc )(1);









218201 2005-01-07
  • 打赏
  • 举报
回复
C++烂就烂在这种地方,太乱了
严重BS
218201 2005-01-07
  • 打赏
  • 举报
回复
用不了,因为不同编译器的实现不一样,导致模块中的名称不一致

对于函数和变量可以用C标准来调:
用extern "C"{}声明
在BCB中用coff2omf.exe转换导入LIB的格式(注意,不是导入库这个工具转不了)

对于要使用类,在Windows平台下建议写成COM的方式,这样使用对象就方便了

-----------------------------------------
〉〉难道说obj文件也有OMF与COFF之分啊!?
大大的有,
但是就算格式一样,里面的名称不同编译器还是不一样的,一样用不了
jishiping 2005-01-06
  • 打赏
  • 举报
回复
你有coordinate.obj文件?那么就是说你有coordinate.cpp源程序了?有源程序还不好办?就不要那么费事了。
shally5 2005-01-06
  • 打赏
  • 举报
回复
现在我将动态DLL文件的OBJ文件加入工程中,
编译时显示:
[Linker Error]'C:\tesldll\coordinate.obj' contains invalid OMF record.type 0x4c(possibly COFF)
难道说obj文件也有OMF与COFF之分啊!?
jishiping 2005-01-06
  • 打赏
  • 举报
回复
如果你一定要使用这个DLL中的class,一个笨方法,就是自己用VC再写一个DLL,这个DLL中导出一个函数,通过这些函数来操作原来的DLL中的class,比如:
void* __export __stdcall CreateCoord()
{
return new Coordinate();
}

void __export __stdcall ReleaseCoord(void* pData)
{
delete (Coordinate*)pData;
}

int __export __stdcall Calculate(void* pData, int ParOne,int ParTwo)
{
return ((Coordinate*)pData)->Calculate(ParOne, ParTwo);
}
jishiping 2005-01-06
  • 打赏
  • 举报
回复
函数Calculate是class CCoordinate中的一个成员函数,用GetProcAddress(hInst,"Calculate");得到的当然是NULL。对于VC的DLL中的导出的class,以前没有遇到过,不知道怎么处理(我从来没有用VC写过程序)。你传给我的文件中的aaa.lib,应该是用BCB的coff2omf.exe转换得到的,里面什么也没有。但是用inplib生成的lib文件,里面有导出的class,但是连接时还是提示找不到相应的函数,应该是VC中的描述和BCB中的描述不同导致的,但是我自己更改头文件,还是无法解决。不过有一点
可以肯定,DLL中导出类的方法,这样的写法是不通用的。
jishiping 2005-01-06
  • 打赏
  • 举报
回复
看了楼主传给我的DLL文件,以及2个头文件Imports.h、ldf_Info.h,楼主确实表达不清啊。其实
楼主的意思就是:VC写的DLL,有一个class是导出了的,在VC中可以直接使用DLL中的这个class,
但是BCB中却无法直接使用DLL中的这个class。下面是VC中导出的class的描述:

#define DLLIMPORT __declspec(dllimport)

class DLLIMPORT CCoordinate
{
public:
CCoordinate();
virtual ~CCoordinate();

int Calculate(int ParOne,int ParTwo); // Test function
double Rad2Dms(double Rad);
double Dms2Rad(double Dms);
void xy2BL(double x, double y,double &B,double &L);
void BL2xy(double B, double L,double &x,double &y);

double GetLatPrecision(double dKm);
double GetDistance(double dLon1, double dLat1, double dLon2, double dLat2);
double GetArea(double dLat, double &dX, double &dY);
int GetProjectionTypeInteger();
void SetProjectionType( int iProjectionType);
double GetArea(int iX, int iY);
double GetRadius(double fLat);

// sal modify
void Setup(tagLDFFileHeader &ldfFileHeader, float fEnlarge = 1.0f);
void SetupByLatLonRange(int ProjectionType, double dMinLat, double dMaxLat, double dMinLon,
double dMaxLon, int iWidth, int iHeight, TRect rectMargin, double dEnlarge);
void Setup(int ProjectionType, double dCenterLon, double dCenterLat, double dLatPrecision, int iWidth,
int iHeight, double dStandardLon, double fEnlarge);
void Setup(int ProjectionType, double dCenterLon, double dCenterLat, double dLatPrecision,int iWidth,
int iHeight);
float GetAlbersLat(double L);
double GetAlbersRadius(double dLat);
float Alpha(float lon);
bool LatLon(double x, double y, float &Lon, float &Lat);
bool XY(double Lon, double Lat, int &X, int &Y);
bool XY(double Lon, double Lat, double &X, double &Y);

tagPROJECTIONTYPE m_eProjectionType;

int m_iPicture_Width; // for fixed size picture only
int m_iPicture_Height;
TRect m_DispRect;

// sal added
double m_dEnlarge;
double m_dRearth ;
BOOL m_isbPreject;

// qjh added
double a, f, e2; // »ù±¾ÍÖÇò²ÎÊý
double A1, A2, A3, A4; // ÓÃÓÚ¼ÆËãXµÄÍÖÇò²ÎÊý
double L0, L0FUDU; //ÖÐÑë¾­¶È
double m_dCenterKm_x, m_dCenterKm_y;
double dLatPrecision_KM;
double dCenterX,dCenterY;

//Parameters for convert to screen coordinate
double m_dFactor;
double m_dX0, m_dY0, m_dA0PI;
double PI180, PI90;
double m_dCenterLat, m_dCenterLon;
double m_dStandardLon;
double m_dAlbersRadius[9000];
};
shally5 2005-01-06
  • 打赏
  • 举报
回复
abcd果然是空的,为什么啊!导入是空的?
加载更多回复(2)

13,822

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧