如何显式调用DLL中的类(无头文件)

Greenfire 2009-02-27 12:24:42
只有一个DLL文件,现在想使用其里面一个类的功能

比如:
Function Ordinal FileName
_MyApp::Beep 1610809399 (0x60030037) MyLib.Dll *\MyLib.Dll COM Method

要怎样做才能使用Beep函数呢?
...全文
972 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
wwwhhb4002 2009-03-13
  • 打赏
  • 举报
回复

学习
捕鲸叉 2009-03-10
  • 打赏
  • 举报
回复
如果它导出了,就可以用
  • 打赏
  • 举报
回复
如果是com就用#import
如果是一个未知的dll必须逆向。正如我列出来的方法。
nieoding 2009-03-03
  • 打赏
  • 举报
回复
在不修改源DLL的前提下,据我所知,是没有办法的

除非修改dll,增加1个对类实例化的API函数

这也是COM DLL的工作机制,任何Com都会有ComInit和ComExit 2个API函数暴露的
Greenfire 2009-03-02
  • 打赏
  • 举报
回复
各位大大在吗?帮帮忙
oyljerry 2009-03-01
  • 打赏
  • 举报
回复
这个表明这个dll是一个com组件DLL,你要想调用MyFunction就需要知道它的接口参数各种信息等...

DllRegisterServer 等是用来注册com组件的,regsvr32通过这个来注册
Greenfire 2009-03-01
  • 打赏
  • 举报
回复
搞了一天,结果弄得晕头转向,一会儿LoadLibrary一会儿#import都不知道怎么办了

刚才用LoadLibrary调用COM DLL的DllRegisterServer函数来注册,没出现问题,不知道这样行不行?代码如下:
========================
typedef HRESULT (WINAPI * FREG)();
TCHAR szWorkPath[ MAX_PATH ];

HMODULE hDLL = ::LoadLibrary(_T("..\\MyClass.dll")); // 动态装载组件
if(hDLL)
{
FREG lpfunc = (FREG)::GetProcAddress( hDLL, "DllRegisterServer" ); // 取得注册函数指针
// 如果是反注册,可以取得"DllUnregisterServer"函数指针
if ( lpfunc ) lpfunc(); // 执行注册。这里为了简单,没有判断返回值
::FreeLibrary(hDLL);
}

::SetCurrentDirectory(szWorkPath); // 切换回原先的进程工作目录
========================

如果这样行的话,接下来应该怎么做才可以使用 MyFunction::InputBox 呢?



==============================================================
关于用#import
用PE Explorer查看了MyClass.dll的组件
其中TYPELIB中的主要内容如下
=================
//MyClass 1.0 Type Library
//版本号: 1.0
MyClassLib;
GUID = {5FD5723F-D6F6-4F31-A7D0-318E72D28E80};


//MyClass Class
构件类 MyFunction;
GUID = {EF94624F-EAAE-47CA-BE5B-86FDBF0B2BBA};

//MyFunction Interface
分派 MyFunction;
GUID = {DF4F905C-0961-4464-8460-DD2A1F274D1F};
function QueryInterface(riid: ^GUID; out ppvObj: ^^VOID); stdcall;
//method InputBox
function InputBox(strPrompt: BSTR): BSTR; stdcall;

.......
=================

REGISTRY内容如下
=================
HKCR
{
MyClass.MyFunction.1 = s MyFunction Class'
{
CLSID = s '{EF94624F-EAAE-47CA-BE5B-86FDBF0B2BBA}'
}
MyClass.MyFunction = s MyFunction Class'
{
CLSID = s '{EF94624F-EAAE-47CA-BE5B-86FDBF0B2BBA}'
CurVer = s MyClass.MyFunction.1'
}
NoRemove CLSID
{
ForceRemove {EF94624F-EAAE-47CA-BE5B-86FDBF0B2BBA} = s 'MyFunction Class'
{
ProgID = s 'MyClass.MyFunction.1'
VersionIndependentProgID = s 'MyClass.MyFunction'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'TypeLib' = s '{5FD5723F-D6F6-4F31-A7D0-318E72D28E80}'
}
}
}
=================
使用#import的测试不知道怎么办,如果有上面这些信息能不能使用了呢?
Greenfire 2009-03-01
  • 打赏
  • 举报
回复
刚才看到MSDN中对 DllCanUnloadNow等函数的描叙

=============================
DLL 中的自动化

更新:2007 年 11 月

当在“MFC DLL 向导”中选择“自动化”选项时,向导为您提供下列内容:

起始对象描述语言 (.ODL) 文件

STDAFX.h 文件中面向 Afxole.h 的 include 指令

DllGetClassObject 函数的实现,此函数调用 AfxDllGetClassObject 函数

DllCanUnloadNow 函数的实现,此函数调用 AfxDllCanUnloadNow 函数

DllRegisterServer 函数的实现,此函数调用 COleObjectFactory::UpdateRegistryAll
============================

可惜没有找到如何使用,是不是要显示调用DLL ,LoadLibrary DLL后,要先调用里面的 DllRegisterServer 才能使用MyFunction类呢?
Greenfire 2009-03-01
  • 打赏
  • 举报
回复
这是调用他人的DLL,用dllexp查看里面的主要内容如下:

Function Name Address Ordinal Type
DllCanUnloadNow 0x1002d61 1(0x1) Exported Function
DllGetClassObject 0x1002c93 2(0x2) Exported Function
DllRegisterServer 0x1002dac 3(0x3) Exported Function
DllUntergisterServer 0x1002dbb 4(0x4) Exported Function
MyFunction::InputBox 1(0x1) COM Method
MyFunction::SetAdder 2(0x2) COM Method
....


这样只有一个DLL文件,有上面的信息,能不能调用它里面的InputBox等函数,该怎么做呢?
oyljerry 2009-03-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 Greenfire 的回复:]
To:LBPeking
没有源码,是他人的一个DLL

To:zhi_shui_yu
如果要获取的函数有不同的参数和返回值怎么办呢?
[/Quote]
这个你总需要有点函数信息等,不然,你就需要反汇编等来分析参数,返回值了...
zhi_shui_yu 2009-03-01
  • 打赏
  • 举报
回复
如果要获取的函数有不同的参数和返回值怎么办呢?

你可以多定义几个函数指针指向不同的函数类型,或者有个好的方法,就是在dll里面建个统一的接口,但是如果是他人的一个DLL就不行了
biweilun 2009-03-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhi_shui_yu 的回复:]
首先你要保证你的dll有申明你所用到的类的导出接口,然后用LoadLibrary函数load你的DLL,用GetProcAddress函数找到接口就可以了,我过去用过的

HINSTANCE hLib = NULL;
hLib = ::LoadLibrary(szPath); //szPath,你的dll所在的位置
if(hLib == NULL) return false;

DllGetFun fFunc = (DllGetFun)::GetProcAddress((HMODULE)hLib,"BEEP");
// DllGetFun 为函数指针,BEEP为DLL export的函数名
if (fFunc)
{

[/Quote]

这个说得和类一点关系也没有。
LZ说的是COM呢.....

要用#import的
oyljerry 2009-03-01
  • 打赏
  • 举报
回复
就是接口函数参数,返回值等这一类东西,对于Com组件来说,给别人使用就需要开放接口信息,不然别人不能调用
Greenfire 2009-03-01
  • 打赏
  • 举报
回复
"接口参数各种信息"指的是哪些呢?
还没接触过COM,刚才去下载《COM本质论》,还在看
cnzdgs 2009-02-27
  • 打赏
  • 举报
回复
如果是com接口,可以在代码中用#import "xxx.dll"的形式导入,也可以用工具来分析。
如果是DLL的导出类,可以说是没法调用的,除非完全清楚地了解该类。
Greenfire 2009-02-27
  • 打赏
  • 举报
回复
To:LBPeking
没有源码,是他人的一个DLL

To:zhi_shui_yu
如果要获取的函数有不同的参数和返回值怎么办呢?
skybblue 2009-02-27
  • 打赏
  • 举报
回复
如果是Com的话,用#Import方式比较方便,如果不是的话,只能用Depends查处导出函数信息,然后根据序号得到函数地址,然后再调用了
zhi_shui_yu 2009-02-27
  • 打赏
  • 举报
回复
首先你要保证你的dll有申明你所用到的类的导出接口,然后用LoadLibrary函数load你的DLL,用GetProcAddress函数找到接口就可以了,我过去用过的

HINSTANCE hLib = NULL;
hLib = ::LoadLibrary(szPath); //szPath,你的dll所在的位置
if(hLib == NULL) return false;

DllGetFun fFunc = (DllGetFun)::GetProcAddress((HMODULE)hLib,"BEEP");
// DllGetFun 为函数指针,BEEP为DLL export的函数名
if (fFunc)
{
fFunc(); //BEEP()
}
闪破风浪 2009-02-27
  • 打赏
  • 举报
回复
Dll有源码吗?
华亭真人 2009-02-27
  • 打赏
  • 举报
回复
#import"xxx.dll"

LoadLibrary

GetProcAddress
加载更多回复(2)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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