大问题:Authorware为什么不能调用我用VC编写的DLL?
每执行到DLL中的函数时就弹出消息“Authorware遇到问题需要关闭,是否发送错误报告”
在VC编写DLL时,有三种函数调用约定__stdcall, __cdelc, __fastcall,我都试过了,只有__cdelc可以被Authorware Load进来,可是运行时为什么不行?我在VC里测试过了DLL能够正确调用
如果这种方法不行的话,哪位大哥能提供一份VC如何编写UCD的文档?我不会用Delphi
[解决办法]
补充一下,当函数不带参数的时候调用成功。
例如:
int function1()
{
return 3;
}
没问题,但如下的形式就不行:
int function2(int a, int b)
{
return a + b;
}
猜想仍然是参数传递的问题。
[解决办法]
加QQ:83039548我发一些相关的资料给你.关于C++制作U32文件的
[解决办法]
关键点在于资源文件,而其它部分跟标准的API DLL没差别,只是数据类型的对应.
[解决办法]
唉,四年没有接触Authorware,要不是刚才有朋友翻出02年的贴找我要资料,我还真给忘记了有这么回事.
-------------
Authorware以其强大的功能成为当今世界上著名的多媒体系统开发工具软件,它具有丰富的变量和函数,但光靠这些远远不能满足开发的需求,这时就要用到Authorware的动态链接库功能。
一、动态链接库的调用
Authorware通过调用动态链接库来增强其功能。动态链接库是一种在运行是连接的可执行代码和数据模块,它是Windows系统的重要组成元素。Windows通过动态链接库提供了WindowsAPI函数和资源,为软件开发人员创造了良好的编程环。Authorware可以调用Windows系统使用的DLL库中的函数。方法也很简单,运行Authorware程序(笔者使用的是Authorware3.5),在DATA菜单中有两项ShowFunction和LoadFunction,打开ShowFunction菜单,Funtions对话框中有一个Load按钮,这个按钮在选择了Category中的系统函数类时是被禁止的,它的作用和DATA菜单中的LoadFunction的是一样的,都是选择所要加载的函数。加载的函数类型是.ucd(16位版本)、.u32(32位版本)、.dll,其中的UCD和U32是符合AuthorwareDLL转换标准的一层透明扩展。动态链接库是专为编程人员设计的,对于非专业人员来说很不方便,因此Authorware中设计了USERCODE的扩展标准,实际上是在DLL的基础之上再加入一些代码,方便不熟悉DLL的用户使用。在下面我们会看到具体的应用。
一个DLL库中有许多标准的函数库,要使用其中的某个函数还必须指定函数名和相应的参数和返回类型。这里首先说明Authorware中使用的数据类型,因为Authorware和一般的高级编译语言或Windows所使用的数据类型不一致,需要进行参数类型转换。Authorware支持以下几种参数类型,类型转换见下表:
Authorware参数类型相应的Windows或C语言
参数类型
charchar
byteunsignedchar,BYTE
shortint,short,BOOL
wordunsigned,HANDLE,HGLOBAL,
HWND,UINT,WORD
longLONG,long
dwordunsignedlong,DWORD
floatfloat
doubledouble
pointerfar,LPRECT,LPPOINT
stringLPCSTR,LPSTR
voidvoid,VOID
注:void单独出现在参数列表中表示无参数调用。
关于AuthorwareDLL调用中的返回类型转换与上表基本类似,不同之处在string类型的返回值代表的是一串以ι0结尾的字符串的句柄。
参考上面的参数和返回类型转换表以及WindowsSDK开发手册,就可以调用Windows的系统动态链接库中的标准函数了。下面举例说明Authorware调用动态链接库。首先,打开VisualC++,利用VC带的帮助了解库函数,SearchWinHelp关键字可知,WinHelp函数作用是在当前的窗口打开所需的帮助函数,BOOLWinHelpHWNDhWndMain,LPCTSTRlpszHelp,UINTuCommand,DWORDdwData)。其中有四个输入参数,返回一个BOOL值。hWndMain是要求打开帮助的窗口句柄,lpszHelp指向帮助文件所在的字符串,uCommand是帮助的类型值,dwData是关键字。当uCommand为2时表示退出帮助,为3时表示打开帮助索引,为4时表示打开helponhelp,以上三个值均忽略了dwData值。当uCommand为257时,打开帮助主题中dwData指定的关键字。对WinHelp函数有一定了解后,现在看一下这个例子。
打开Authorware的16位版本,建立一个新文件,选择Data菜单下的LoadFunction,选择Windows系统目录下的user.exe文件,出现对话框显示user.exe不包含函数定义,要求用户输入函数名、参数类型、返回值和对函数进行描述。这时我们依次输入WinHelp(注意大小写)、word,string,word,string(上面的函数定义了四个参数,从类型转换表中找出对应的Authorware类型)、short(BOOL型对应short),在描述框中随意记录一下调用信息。按下LOAD后显示调用成功。拖一个Calculation图标到流程线上,在其中输入:
result:=WinHelp(WindowHandle,″c:ιιpwin95ιιwinhelp.hlp″,3,″″)
这里解释一下WindowHandle是系统变量,表示当前Presentation窗口的句柄,第二个参数是帮助文件名和所在路径,3表示打开winhelp的索引,关键字忽略。运行这个文件,果然winhelp.hlp帮助文件被调出。将上面的3改为257,关键字设为BackButton运行时打开帮助文件并显示已找到的主题。大家自己还可以试一下2退出帮助,这里就不赘述了。
需要注意的是,在Authorware的32位版本中,不能调用16位的动态链接库。后经笔者分析user32.dll,发现WinHelp函数变为WinHelpA和WinHelpW,这里说一下调用WinHelpA。过程和16位版本的类似,调入user32.dll,输入WinHelpA函数名,后面和前面介绍的一样,在Calculation图标中调用函数用WinHelpA函数名,显示的结果都一样。一般来说所有16位版本的动态链接库函数都有32位的与之对应,用VC++带的dumpbin分析即可,调用参数基本一致。
二、Authorware的DLL扩充UCD(usercode)
前面所述的动态链接库调用对于Windows程序员来说并不困难,但Authorware应用软件的开发人员常常并不熟悉,所以整个过程有些不够方便。Authorware为此还提供了UCD库,UCD(16bi1t版本)和u32(32bit版本)是Authorware为不熟悉WindowsSDK的人专门准备的DLL的透明扩充。说起来也很简单,就是在生成DLL时,预先把上面的类型转换过程作完了。通过前面介绍,我们知道了类型转换的内容,在UCD、U32中类型以一个大写字母出现。C=char、B=byte、I=short、W=word、L=long、U=dword、P=pointer、F=float、D=double、S=string、V=void。在DLL的re
source文件中对参数类型和返回类型预先作说明,在调用UCD或U32库文件时就能很直观的选择函数名了。
在Authorware的目录下有个winapi.ucd的库,采用同上面一样的调用方法可以看到函数列表框,选择WinHelp函数直接加载并不需要输入类型和返回值。利用上面介绍的同样的方法测试一下这个函数,可以看到效果是一致的,UCD确实起到简化的作用,那么如何编制自己的UCD文件呢?
三、制作UCD、U32实例
通过第一、第二部分的介绍,相信大家对Authorware的动态链接库调用和UCD的概念有一定了解。这一部分主要通过实例的方式使大家对完整的过程有个认识。
首先,制作一个完备的动态链接库。在这个库中我将实现弹出消息框、BEEP一声、返回当前Windows目录的功能。主文件程序如下:
1、sample.cpp
#include
BOOLWINAPIDllEntryPoint(//动态链接库的入口函数
HINSTANCEhinstDLL,//handletoDLLmodule
DWORDfdwReason,//reasonforcallingfunction
LPVOIDlpvReserved)//reserved
{switch(fdwReason)
{caseDLL—PROCESS—ATTACH:
{break;}
caseDLL—PROCESS—DETACH:
{break;}
}
returnTRUE;
}
intBEEPSOUND(void)
{MessageBeep((WORD)-1);
return1;}
GLOBALHANDLEWINDOWSPATH(void)//返回WINDOWS所在路径
{
LPTSTRlpBuffer;
UINTuSize=50;
GetWindowsDirectory(lpBuffer,uSize);
intlength=lstrlen(lpBuffer);
GLOBALHANDLEhgString=GlobalAlloc(GHND,length+1);
if(hgString==NULL)
{MessageBox(NULL,″Can'tgetwindowspath″,″warning″,
MB—OK MB—ICONEXCLAMATION MB—TASKMODAL);}
else
{LPSTRtempstring=(LPSTR)GlobalLock(hgString);
lstrcpy(tempstring,lpBuffer);
GlobalUnlock(hgString); }
return hgString;
}
voidMBOX(LPSTRtext)//此函数显示消息框
{MessageBox(NULL,text,"示范程序消息框",MB_OK
[解决办法]
补充(汗死,只能回复三次):
-------------------------
Creating the resource file
The last thing we need to do is to add the UCD resource, so that APW can directly load the functions. To do this, we need to make up a .rc file, and then compile it into a .res file.
Start Notepad. This is what is used to create the resource file.
Add all this code; I will explain something about it afterwards.
1 DLL_HEADER PRELOAD DISCARDABLE
BEGIN
"Add\0",
"UCase\0",
"\0"
END
Add DLL_HEADER PRELOAD DISCARDABLE
BEGIN
"\0",
"I\0",
"II\0",
"Result := Add( Num1, Num2 )\r\n",
"\r\n",
"Adds two numbers together\0",
END
UCase DLL_HEADER PRELOAD DISCARDABLE
BEGIN
"\0",
"S\0",
"S\0",
"Result := UCase( str )\r\n",
"\r\n",
"Returns the upper case version of str\0",
END
Some explanations:
1 DLL_HEADER PRELOAD DISCARDABLE
BEGIN
"Add\0",
"UCase\0",
"\0"
END
This part describes the functions available. Add each new function on a new line. Each line has a "\0" at the end of it to indicate the end of the function name. The section ends with "\0" on a single line. It doesn't matter what order the functions are listed in.
UCase DLL_HEADER PRELOAD DISCARDABLE
BEGIN
"\0",
"S\0",
"S\0",
"Result := UCase( str )\r\n",
"\r\n",
"Returns the upper case version of str\0",
END
Each function will then be described in it's own section. Note that the functions can be listed in any order.
The section starts with a single line with "\0".
The next line lists the Return type.
Use S for string; I for integer; V for void. See the Using Authorware manual for a full list of possible types.
The next line lists the arguments.
If there is more than one argument, place them all together eg "SIIS\0",
What follows then is the description of the function. This will appear in the description box when you load the function. To break the description into lines, place "\r\n" at the end of the line. At the end of the last line of the description, add "\0".
Please note that the layout of this file is very strict - if you do not follow it correctly, then all sorts of strange things will happen when you try to load a function.
on to: Compiling the resource file
back to: Setting some project options Start