为什么这么个简单的DLL会出错?!

trybird 2001-10-13 02:12:16
我太菜了!我要死了!

Test.bpf是生成.dll的工程文件,其中代码如下:

Test.cpp的代码:
//------------------------------------------------------------------------#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#include "Test.h"
#pragma hdrstop
#pragma argsused
//------------------------------------------------------------------------BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
}
//------------------------------------------------------------------------void DoFunc(void)
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}
//------------------------------------------------------------------------

Test.h的代码:
extern "C" __declspec(dllexport) void DoFunc(void);

CallDll.bpr是调用Test.dll的工程,其中的主程式如下:

CallMe.cpp的代码如下:
//------------------------------------------------------------------------
#include <vcl.h>
#include "CallMe.h"
#pragma hdrstop
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
try
{
void (__stdcall *DoFunc)(void);
HANDLE hInst;

hInst = LoadLibrary("Test.dll");
(FARPROC &)DoFunc=GetProcAddress(hInst,"DoFunc");

DoFunc();

FreeLibrary(hInst);
}
catch(...)
{
ShowMessage("Error!!!!!!!");
}
}
//------------------------------------------------------------------------

分别编译后,运行CallDll.exe调用Test.dll,在执行DoFunc()时出错。
出错信息如下:
Access Voilation at address 00000000. Read of address 00000000.

大侠,请问为什么呀?!为什么?!
...全文
264 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
trybird 2001-10-13
  • 打赏
  • 举报
回复
再次多谢了!
我差点就绝望地要把自己给炒掉了!是你们给了我从新改造的再生的机会……

:)
trybird 2001-10-13
  • 打赏
  • 举报
回复
正确的代码:

**********DLL部分
// test.cpp
//--------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#include "Test.h"
#pragma hdrstop
#pragma argsused
//---------------------------------------------------------------------------
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
}
//---------------------------------------------------------------------------
void __stdcall DoFunc()
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}
//---------------------------------------------------------------------------

// test.h
extern "C" __declspec(dllexport) __stdcall void DoFunc();

*********调用DLL的部分:
// CallMe.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#include "CallMe.h"
#pragma hdrstop
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

try
{
void (__stdcall *DoFunc)(void);
HANDLE hInst;

hInst = LoadLibrary("Test.dll");
(FARPROC &)DoFunc=GetProcAddress(hInst,"DoFunc");

DoFunc();

FreeLibrary(hInst);
}
catch(...)
{
ShowMessage("Error!!!!!!!");
}
}
//---------------------------------------------------------------------------
trybird 2001-10-13
  • 打赏
  • 举报
回复
谢谢诸位,尤其是陈杰!还有热心的虚竹和尚及其他兄弟们!

关键就是缺少 __stdcall啊!
加上__stdcall就一切都OK啦!
兄弟们啊,千万别再犯我这么低级的错误了!

一会马上买单,只付帐给陈杰和虚竹和尚,没意见吧?
其实其他兄弟也很热心,只能多谢了!向你们三鞠躬了!
快速开发平台 2001-10-13
  • 打赏
  • 举报
回复
trybird(菜鸟) 

你说“LoadLibaray()和GetProcAddress()在调试时都通过了,是在DoFunc();”,要知道返回空指针照样能够通过。
快速开发平台 2001-10-13
  • 打赏
  • 举报
回复
我把所有工程文件都存入到My Documents目录,程序中涉及目录的地方改一下。
快速开发平台 2001-10-13
  • 打赏
  • 举报
回复
兄弟,我帮你调通了。
代码如下:
Dll.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) void __stdcall DoFunc(void);
void __stdcall DoFunc(void)
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}
//------------------------------------------------------------------------
实现部份:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
typedef void __stdcall (*TDoFunc)(void);
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
TDoFunc DoFunc;
int LibHandle;

LibHandle = (int) LoadLibrary("C:\\My Documents\\project2.DLL");
DoFunc=(TDoFunc)GetProcAddress((TDoFunc)LibHandle,"DoFunc");
DoFunc();
}
//---------------------------------------------------------------------------
原因可能是你没有载入Dll,请查看DoFunc是否为空。其他不明请问。
xycleo 2001-10-13
  • 打赏
  • 举报
回复
没道理阿!!!
那就是下面的除了问题
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);

你试一下把他放在try...catch里
是不是根本没有xxx.txt这个文件
i25ffz 2001-10-13
  • 打赏
  • 举报
回复
hi! trybird, try it ......

試試上面的, 別泄气......
快速开发平台 2001-10-13
  • 打赏
  • 举报
回复
我帮你调试一下吧,稍等...
trybird 2001-10-13
  • 打赏
  • 举报
回复
改了啊!

原来是——
extern "C" __declspec(dllexport) void DoFunc(void);

现在是——
extern "C" __declspec(dllexport) void DoFunc();

但出错依旧啊!完了!我明天改行吧!从此去也!
i25ffz 2001-10-13
  • 打赏
  • 举报
回复
Sorry......

Test.cpp的代码:
//------------------------------------------------------------------------#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#include "Test.h"
#pragma hdrstop
#pragma argsused

//add code
TApplication* oApp = Application;

//------------------------------------------------------------------------BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
//add code
if (reason == DLL_PROCESS_ATTACH)
{
oApp = Application;
}

if (reason == DLL_PROCESS_DETACH)
{
Application = oApp;
}
//end add

return 1;
}
//------------------------------------------------------------------------void DoFunc(void)
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}
//------------------------------------------------------------------------
know more, see BCB help.
Try it ......
i25ffz 2001-10-13
  • 打赏
  • 举报
回复
Test.cpp的代码:
//------------------------------------------------------------------------#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#include "Test.h"
#pragma hdrstop
#pragma argsused

TApplication* oApp = Application;
//------------------------------------------------------------------------BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
return 1;
if (reason == DLL_PROCESS_ATTACH)
{
oApp = Application;
}

if (reason == DLL_PROCESS_DETACH)
{
Application = oApp;
}
}
//------------------------------------------------------------------------void DoFunc(void)
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}
//------------------------------------------------------------------------
Try it ......
xycleo 2001-10-13
  • 打赏
  • 举报
回复
还有extern那里??改了吗!!!??????
trybird 2001-10-13
  • 打赏
  • 举报
回复
救命啊!!!~~~~~~~~~~~~~
trybird 2001-10-13
  • 打赏
  • 举报
回复
试了啊!
原来是——
void DoFunc(void)
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}

改成了——
void DoFunc()
{
FILE *fs=fopen("XXX.txt", "a");
fprintf(fs,"I am a Programmer.");
fclose(fs);
}

Build后,故障依然如故啊!
xycleo 2001-10-13
  • 打赏
  • 举报
回复
你调用时是Dofunc()什么都没传给他!!

去掉了,当然不会有提示阿1!
xycleo 2001-10-13
  • 打赏
  • 举报
回复
应该就是这里了1!我在我这里试了!!去掉DoFunc(void)里的void

可以阿
trybird 2001-10-13
  • 打赏
  • 举报
回复
LoadLibaray()和GetProcAddress()在调试时都通过了,是在DoFunc();那一句出的错!
真的。我把DoFunc();这一句屏蔽掉就不会出错了。

这个程序极简单,你们都可以试一下嘛,所有代码就这些!
唉,就这么个都搞不定~~~~~~~~唉唉唉~~~~!
xycleo 2001-10-13
  • 打赏
  • 举报
回复
你改了吗??????????
csdnflysnow 2001-10-13
  • 打赏
  • 举报
回复
这个程序有两个严重的隐患.

1. LoadLibaray 没有判断返回值,记加载DLL是否成功.
如果这里都没成功.后面更错了.

2. GetProcAddress 也没有判断,可能该DLL未找到该函数.

从你的程序来看, 我怀疑错误应该是在第一部,即加载DLL失败.

查查看吧.
加载更多回复(13)
程序名称:OllyDBG版 本:1.10汉 化 人:cao_cong联系方式:cao_cong_hx@yahoo.com.cn汉化日期:2005.11.28汉化说明: 本来是想等 OllyDBG 2.0 出来再汉化的,可看到dyk158兄弟的修改版说明中对我原来汉化版本的汉化质量提了一点小小的意见,想想也是,我原来的汉化版是OllyDBG 1.10 的最终版本刚出来时汉化的,距今已经一年多了也没有更新过,当时只顾不出因汉化造成的Bug,汉化嘛确实不咋的。看到BoOMBoX/TSRh2004他们制作的美化界面,确实也觉得漂亮,最后决定再出个汉化版本。这个版本的汉化加测试、修改花了我整整两个星期的业余时间,其中的非标字符对照文本有4000多行,看一遍都半天。这个版本中的所有翻译我都重新过了几遍,绝大部分都重新翻译过,力求做到准确,希望能给大家一个比较完美的汉化版本。在制作过程中参考了TT小组翻译的OllyDBG帮助及dyk158修改、聆风听雨汉化的ODbyDYK修改版,主要是想让翻译更准确一点,能让新手把汉化版和TT小组汉化的帮助文档对照起来学习。在此对以上提到的各位表示衷心的感谢! 这个软件汉化起来确实是个苦差事,不光是要翻译的资源多,还有一个重要的方面就是稍不留神就出现汉化引起的Bug。经常是用原版来调试汉化版找问题,象原来菜单上的“&Window”汉化后出错,还是调试后才知道原来它内部加载菜单时还有个这个“&Window”,只有两个都汉化才不出错。另外其它的许多问题都只好靠调试来解决。原来汉化时又没有把要注意的地方写下来,这次光测试就花了好几天。 这个汉化版本除因汉化必要而打补丁外,我不准备再对它打任何补丁。一是我怕打补丁影响 OllyDBG 的兼容性;二是已经有Fly和dyk158他们做了,我想我自己再做的话也不比他们做的更好;三是我实在是感到太累了!如果大家要想要修改的版本的话,推荐使用freecat兄弟制作的AutoPath,我把这个插件放在 FixOD 目录下,我把freecat兄弟发布时所用的说明也放在同一目录下,大家可以根据说明来使用这个插件改造你的OllyDBG。 在这里我要感谢看雪论坛上的看雪老大和论坛上各位兄弟的支持,正是有了他们的测试和建议,经过多次修正后,才有了今天的这个最终版本,由衷的感谢看雪论坛上的各位兄弟!汉化第二版主要更新:1、界面采用 BoOMBoX/TSRh2004 制作的美化界面,主要为了好看一点。2、绝大部分句子都重新翻译过,力求做到准确。3、配置文件中除字体、语法高亮、颜色这几个部分保留为中文外,其它的都恢复为英文。保留字体、语法高亮、颜色这几个部分为中文的目的是因为我发现若先运行过英文版配置好后,汉化版中对应这几个部分的一些菜单也取原英文版配置中的英文字串,而不是汉化过的字串。我觉得翻译后既能保持与英文版的兼容性,又能让英文版与中文版的界面等互不干扰。4、dyk158 建议我把配置文件中的字体、语法高亮、颜色这几个部分恢复为英文,我专门做了个恢复为英文配置的补丁(如果你以前运行过英文版进行了相应配置,则补丁后的汉化版本对应这几个部分的相应菜单将显示英文,若你是用打过这个补丁的汉化版本生成配置文件,则相应菜单将显示中文)放在英文配置补丁目录下,需要字体、语法高亮、颜色这部分也用英文配置的朋友可以把这个补丁放到我做的汉化版的安装目录,选择 Ollydbg.exe 补丁就可以了。这个补丁同样适用于原版界面的汉化版本。5、上一版中部分未汉化的内容这次除了不能汉化的外,基本上都已汉化。6、另有一个界面未作美化的汉化版放在原版界面目录,可以按自己的喜好选择使用哪一个。7、FixOD 目录下放的是用 freecat 的 AutoPath.dll 打过补丁的 OllyDBG,使用前请先备份好你原来的Ollydbg.exe文件,再把这个目录下的Ollydbg.exe、AutoPath.dll、AutoPath.ini复制到你的OllyDBG安装目录下就可以了。在上一版的基础上,插件做了如下更新:1、脚本插件 ODbgScript.dll (v1.23 汉化版)2、快捷命令插件 CmdBar.dll (v3.10.109c 汉化版,这个版本有支持运行 OllyScript 脚本的命令:OSC)3、标签插件 Labeler.dll (v1.33.108 汉化版)4、图表插件 OllyFlow.dll (v0.71 汉化版,我从IDA中提取了个wingraph32.exe放在插件目录下,用于配合这个插件)5、断点管理 olly_bp_man.dll (汉化版,在我机器上不能用,放在备用目录)6、字串参考修改版本 ustrrefadd.dll (汉化版)另外还添加了dyk158 汉化的两个插件:1、脱壳插件 OllyDump.dll (V3.00.110 dyk158 汉化版)2、脱壳插件 pedumper.dll (v3.03 dyk158 汉化版) 推荐大家试用一下这两个插件:ApiBreak 插件,用于在对话框、字串、注册表、时间、内存等 API 函数上设置断点,还可设置万能断点,简单易用;GODUP 插件,包含 Map 载入器、资源查看器、进程查看器、IDA 签名载入程序及自带的一个记事本这五个工具。感觉它自带的记事本用来在调试时记一些东西比较方便。 如果你以前没用过OllyDBG的话,我要提醒你使用前先在菜单的 选项->界面->目录 中把插件和 UDD 的路径设置好,以免影响使用! 此汉化版中的插件除了一个 PuntosMagicos.dll 插件没汉化外(我实在是弄不懂是哪国语言),其它的插件都已汉化。目录下的OLLYDBG.HLP帮助文件是由TT小组翻译的中文帮助,在此对TT小组的辛勤劳动表示感谢!(OLLYDBG_EN.HLP为原版英文帮助)声明: 1.本汉化软件包内的所有英文及其他语言的源程序的版权归原作者(公司)所有。 2.本人不对使用本汉化软件造成的任何情况的损失负责。 3.本汉化软件仅供学习研究之用。严禁用于商业用途。本人不对使用本汉化软件造成的任何法律纠纷负责。 4.如果你对本汉化软件有什么建议请联系我。 5.请在转载时保留此汉化版的完整性。

13,873

社区成员

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

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