![]() |
【转帖】[原创]arx调用dll中的函数
[原创]arx调用dll中的函数
www.dimcax.com [原创]arx调用dll中的函数 在网上曾经看见有人问这样的一个问题:在arx中如何调用另一个arx中所定义的函数。对于这个问题,我不知道他真正的用意何在,但从技术而言,这是可以做到的。windows系统把大部分的函数和功能都封装在dll中供其它程序调用,从节约内存开支和压缩应用程序大小而言都是意义重大的。因此,看到上面这个朋友提的这个问题,我就有了另外一个想法:把arx中常用的函数封装在dll中供其它程序调用岂不是更好。 于是,我开始着手研究这方面的工作,可是,进程并不如想象中的美好。在纯mfc中程序没有问题,一使用arx中的函数就出问题,搞了好长一段时间都不出结果,加之网上一点这方面的资料都没有,刚开始还怀疑是autodesk公司在arx函数中做了手脚,可是rax在本质上也是dll啊,本着不成功誓不罢休的角度出发,终于探出了点眉目。再次声明,由于本人水平有限,加之这方面资料匮乏,难免有遗漏或不正确的地方,还望朋友们指出。 下面这个例子是把addtomodelspace()函数添加到dll中,然后在arx程序中调用它。函数的功能是把对象添加到数据库中,并返回对象的id。 一、创建dll工程 1、启动vc++6.0并新建一个名为adesksampe的mfc appwizard(dll)工程。 2、选择 regular dll using shared mfc dll(动态链接库使用共享mfc dll) 选项创建工程。 3、链接arx库文件。 在[工程]-[设置]-[连接]-[对象/库模块]中添加下面几个链接: rxapi.lib acrx15.lib acdb15.lib acutil15.lib acge15.lib acgiapi.lib achapi15.lib acismobj15.lib acad.lib acedapi.lib acsiobj.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib 4、将指定的函数名添加到def文件的exports中 exports ; explicit exports can go here ;本例中要添加的函数 addtomodelspace 5、打开adesksampe.h文件添加函数声明: 该头文件声明了要供其它应用程序调用的函数原型。在这个例子中我只增加了一个函数addtomodelspace(),它用于把arx中的对象添加到数据库中。 //需要包含的头文件 #include "geassign.h" #include "dbsymtb.h" // symboltables #include "dbapserv.h" // acdbhostapplicationservices() #include "dbtrans.h" // actransaction #include "actrans.h" // actransactionmanager #include "acdb.h" // acdb definitions #include "rxregsvc.h" // arx linker #include "aced.h" // aced stuff #include "adslib.h" // rxads definitions #include "dbents.h" #include "resource.h" // main symbols //这条语句是新增加的导出函数声明 __declspec(dllexport) acad::errorstatus winapi addtomodelspace(acdbobjectid &objid, acdbentity *pent); class cadesksamperapp : public cwinapp { ............ }; 5、打开adesksampe.cpp文件添加函数实现: cadesksamperapp theapp; __declspec(dllexport) acad::errorstatus winapi addtomodelspace(acdbobjectid &objid, acdbentity *pent) { //注意! //如果此dll是与mfc dll动态链接的,则其输出的任何调用mfc的函数都必须 //在其前面加上afx_manage_state()宏,这个宏必须出现在任何mfc调用之前。 //这意味着它必须是函数内部的第一条语句,甚至在任何对象变量声明之前, //因为它们的构造函数有可能会调用mfc dll。 afx_manage_state(afxgetstaticmodulestate()); acad::errorstatus es = acad::eok; acdbblocktable *pblocktable = null; acdbblocktablerecord *pblocktablerecord = null; es=acdbhostapplicationservices()->workingdatabase()->getsymboltable(pblocktable, acdb::kforread); if( es != acad::eok ) { return es; } es=pblocktable->getat(acdb_model_space, pblocktablerecord, acdb::kforwrite); if( es != acad::eok ) { pblocktable->close(); return es; } es=pblocktablerecord->appendacdbentity(objid, pent); pent->close(); pblocktable->close(); pblocktablerecord->close(); return es; } 二、dll调用 通过前面的例子我们设计了一个动态链接库adesksampe.dll,此库声明了一个函数addtomodelspace()供其它程序调用。下面我们再开发一个arx应用程序,程序将调用刚才设计好的dll。 1、用arx向导新建一个工程,记得一定要把use mfc复选框选中。 2、将上一节dll工程所生成的adesksampe.lib文件和adesksampe.dll文件拷入当前工程所在的目录。 3、在命令执行的文件中添加函数声明,关键字extern把它声明为外部的win api函数,然后在程序中就可以正常使用addtomodelspace()了。 下面是完整的程序清单: // objectarx defined commands #include "stdafx.h" #include "stdarx.h" //指定本文件生成的.obj文件应与adesksampe.lib一起连接。 #pragma comment(lib, "adesksampe.lib") //告诉编译器此函数是在当前程序的外部定义的 extern acad::errorstatus winapi addtomodelspace(acdbobjectid &objid, acdbentity *pent); // this is command 'windo' void windo() { ads_name en; ads_point pt; if(acedentsel("\n选择要分解的对象:", en, pt) != rtnorm) return; acdbobjectid id; acdbgetobjectid(id, en); acdbentity* pent = null; acdbopenobject(pent, id, acdb::kforwrite); if(pent == null) return; acdbvoidptrarray pvoidptrarray; if(pent->explode(pvoidptrarray) != acad::eok) { pent->close(); acedalert("对象不能分解!"); return; } for(int i=0; i<pvoidptrarray.length(); i++) { acdbentity* pexpent = null; pexpent = (acdbentity*) pvoidptrarray.at(i); acutprintf("\n分解后的对象类型是: %s", pexpent->isa()->name()); // 现在,就可以象使用内部函数一样使用它了 if(addtomodelspace(id, pexpent) != acad::eok) delete pexpent; } pent->erase(true); pent->close(); } 三、允许arx程序 程序创建好了,接下来就该运行它看看效果了。在autocad中加载刚才创建好的arx程序,竟然提示找不到指定的动态链接库,无法加载,看来肯定是某个环节出了问题。 其实,windows中的大部分dll文件都放在系统的windows\\system和windows\\system32目录下,这是windows系统缺省的库搜索路径,因此,在加载arx程序前,必须让系统能找到相应的dll文件。所以,在应用程序中调用动态链接库中的函数必须进行适当的设置,我们可以采用以下几种方法: 1、把adesksampe.dll文件复制到系统的system目录下。 2、或者把adesksampe.dll文件所在目录设置成系统搜索路径。 3、或者把dll文件和arx文件放在同一个目录下。 只要做了上面几件事中的任意一件,嘿嘿,应该大功告成了。 |
所有的时间均为北京时间。 现在的时间是 07:21 AM. |