ARX学习中遇到的一个问题-有关acedRegCmds->addCommand!
在帮助中,对函数acedRegCmds->addCommand的参数定义如下:addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,
AcRxFunctionPtr functionAddr,
AcEdUIContext* UIContext = NULL,
int fcode = -1
HINSTANCE hResourceHandle = NULL,
AcEdCommand** cmdPtrRet = NULL)
对参数五就是函数地址,我现在有两个问题:
疑问一:为什么示例中我看到的例子,函数都是无输入参数类型,就是void Func()这种形式,如果我希望有参数该如何实现呀?
疑问二:为什么有的示例在该函数调用中用了函数的取地址操作&,而有的没有,但都能编译通过,这是什么原因?
还望各位大拿指点。
使用函数acedDefun!
QuestionHow can I call an ARX function from AutoLISP so that it can pass arguments into
ARX and return results?
Answer
This can be done using an acedDefun() function in ARX. See the following sample
code that shows how to use the acedDefun. If you are using ObjectARX Wizard,
the Wizard will create all this for you when you use the toolbar button "Cmd"
to invoke the "ObjectARX Defined Commands" dialog. Check the option "acedDefun"
in the dialog to add a command that AutoLISP can call.
// Factorial.cpp
/////////////////////////////////////////////////////////// includes from ObjectARX Wizard
#include "acdb.h" // acdb definitions
#include "adslib.h" // ads defs
#include "rxregsvc.h" // unlock application
// TODO: add your own includes here or in Factorial.h// entry point for this application
extern "C" AcRx::AppRetCode acrxEntryPoint( AcRx::AppMsgCode msg, void* );
// message handlers
static void OnkLoadADSMsg(void);
static void OnkUnloadADSMsg(void);
static void OnkInvkSubrMsg (void);// helper functions
static void initApp(void);
static void unloadApp(void);
static int funcload(void);
static int funcunload(void);
static int dofun (void);
int factorial ();
// end of declaration
// ADS Function Table
typedef struct {
char *name;
int (*fptr)();
} ftblent;#define ELEMENTS(array) (sizeof(array)/sizeof((array)))/* Table of ADS functions */
ftblent exfun[] = {
{"FACTORIAL", factorial},
};
/////////////////////////////////////////////////////////////////////
// funcload(internal)
// This function is called to define all function names in the ADS
// function table.Each named function will be callable from lisp or
// invokable from another ADS application.
/////////////////////////////////////////////////////////////////////
static int
funcload()
{
int i; for (i = 0; i < ELEMENTS(exfun); i++) {
if (!acedDefun(exfun.name, i))
return RTERROR;
} return RTNORM;
}/////////////////////////////////////////////////////////////////////
// funclunoad(internal)
// This function is called to undefine all function names in the ADS
// function table.Each named function will be removed from the
// AutoLISP hash table.
/////////////////////////////////////////////////////////////////////
static int
funcunload()
{
int i; // Undefine each function we defined for (i = 0; i < ELEMENTS(exfun); i++) {
acedUndef(exfun.name,i);
} return RTNORM;
}/////////////////////////////////////////////////////////////////////
// dofun(internal)
// This function is called to invoke the function which has the
// registerd function code that is obtained from acedGetFunCode()
/////////////////////////////////////////////////////////////////////
int
dofun()
{
intval;
intrc; acedRetVoid(); if ((val = acedGetFunCode()) < 0 || val > ELEMENTS(exfun))
return RTERROR; rc = (*exfun.fptr)(); return ((rc == RTNORM) ? RSRSLT:RSERR);
}/////////////////////////////////////////////////////////////////////
// acrxEntryPoint(internal)
// This function is the entry point for your application.
/////////////////////////////////////////////////////////////////////
AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* ptr)
{
switch (msg) {
case AcRx::kInitAppMsg:
acrxUnlockApplication(ptr);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
case AcRx::kLoadADSMsg:
OnkLoadADSMsg();
break;
case AcRx::kUnloadADSMsg:
OnkUnloadADSMsg();
break;
case AcRx::kInvkSubrMsg:
OnkInvkSubrMsg();
break;
default:
break;
}
return AcRx::kRetOK;
}
static void OnkLoadADSMsg(void)
{
funcload();
// TODO: add your message handler code here // end of message handler
}static void OnkUnloadADSMsg(void)
{
funcunload();
// TODO: add your messasge handler code here // end of message handler
}static void OnkInvkSubrMsg(void)
{
dofun();
// TODO: add your message handler code here // end of message handler
}
static void initApp(void)
{
// TODO: init your application} // END initApp()static void unloadApp(void)
{
// TODO: clean up your application // END unloadApp()
}// Here are your new AutoCAD functions. Add your code.
//////////////////////////////////////////////////////int factorial()
{
// TODO: add your code here struct resbuf*pArgs = acedGetArgs();
if( pArgs == NULL ) {
acutPrintf("\nNo Argument supplied\n");
acedRetNil();
return RTNORM;
}
int arg;
if( pArgs->restype == RTLONG ) {
arg = pArgs->resval.rlong;
} else if( pArgs->restype == RTSHORT ) {
arg = pArgs->resval.rint;
} else {
acutPrintf("\nInvalid arguments\n");
acedRetNil();
return RTNORM;
}
if( pArgs->rbnext != NULL ) {
acutPrintf("\nToo many arguments\n");
acedRetNil();
return RTNORM;
}
if( arg <= 0 ) {
// return 0
acedRetInt( 0 );
} else if ( arg >= 171 ) {
// to big for double, return nil
acutPrintf("\nToo big to calculate\n");
acedRetNil(); } else if( arg >= 17 ) {
// too big for long ints, return a double
double factorial = 1.0;
while( arg > 0 ) {
factorial *= arg;
arg--;
}
acedRetReal( factorial );
} else {
// we can handle normally
int factorial = 1;
while( arg > 0 ) {
factorial *= arg;
arg--;
}
acedRetInt( factorial );
} // end of function
return RTNORM;
}
// TODO: add your other functions here
// END
页:
[1]