IoDynLib *IoDynLib_callPluginInitFunc(IoDynLib *self, IoObject *locals, IoMessage *m) { /*doc DynLib callPluginInit(functionName) Call's the dll function of the specified name. Returns the result as a Number or raises an exception on error. */ intptr_t rc = 0; intptr_t *params = NULL; void *f = DynLib_pointerForSymbolName_(DATA(self), CSTRING(IoMessage_locals_symbolArgAt_(m, locals, 0))); if (f == NULL) { IoState_error_(IOSTATE, m, "Error resolving call '%s'.", CSTRING(IoMessage_locals_symbolArgAt_(m, locals, 0))); return IONIL(self); } if (IoMessage_argCount(m) < 1) { IoState_error_(IOSTATE, m, "Error, you must give an init function name to check for."); return IONIL(self); } params = io_calloc(1, sizeof(intptr_t) * 2); params[0] = (intptr_t)IOSTATE; params[1] = (intptr_t)IOSTATE->lobby; rc = ((intptr_t (*)(intptr_t, intptr_t))f)(params[0], params[1]); io_free(params); return IONUMBER(rc); }
void DynLib_open(DynLib *self) { self->handle = dlopen(self->path, RTLD_NOW | RTLD_GLOBAL); /* RTLD_LAZY); */ //self->handle = dlopen(self->path, RTLD_NOW | RTLD_LAZY); DynLib_updateError(self); if (DynLib_hasError(self)) { return; } if (self->initFuncName) { void *f = DynLib_pointerForSymbolName_(self, self->initFuncName); if (!f) { DynLib_setError_(self, "init function not found"); return; } if (self->initArg) { //printf("DynLib: opening with 1 arg %p\n", self->initArg); (*(DynLibOneArgFunction *)f)(self->initArg); } else { (*(DynLibNoArgFunction *)f)(); } } }
void DynLib_close(DynLib *self) { if (self->freeFuncName) { void *f = DynLib_pointerForSymbolName_(self, self->freeFuncName); if (!f) { DynLib_setError_(self, "io_free function not found"); return; } if (self->freeArg) { (*(DynLibOneArgFunction *)f)(self->freeArg); } else { (*(DynLibNoArgFunction *)f)(); } } if (self->handle) { dlclose(self->handle); } self->handle = NULL; }
void *IoCFFILibrary_rawGetFuctionPointer_(IoCFFILibrary *self, const char *name) { DynLib *library = DATA(self)->library; if (!library) { const char *name = CSTRING(IoObject_getSlot_(self, IOSYMBOL("name"))); library = DATA(self)->library = DynLib_new(); DynLib_setPath_(library, name); DynLib_open(library); } return DynLib_pointerForSymbolName_(library, name); }
IoDynLib *IoDynLib_justCall(IoDynLib *self, IoObject *locals, IoMessage *m, int isVoid) { int n, rc = 0; intptr_t *params = NULL; IoSymbol *callName = IoMessage_locals_symbolArgAt_(m, locals, 0); void *f = DynLib_pointerForSymbolName_(DATA(self), CSTRING(callName)); //printf("DynLib calling '%s'\n", CSTRING(callName)); if (f == NULL) { IoState_error_(IOSTATE, m, "Error resolving call '%s'.", CSTRING(callName)); return IONIL(self); } if (IoMessage_argCount(m) > 9) { IoState_error_(IOSTATE, m, "Error, too many arguments (%i) to call '%s'.", IoMessage_argCount(m) - 1, CSTRING(callName)); return IONIL(self); } if (IoMessage_argCount(m) > 1) { params = io_calloc(1, IoMessage_argCount(m) * sizeof(unsigned int)); } for (n = 0; n < IoMessage_argCount(m) - 1; n++) { IoObject *arg = IoMessage_locals_valueArgAt_(m, locals, n + 1); intptr_t p = marshal(self, arg); params[n] = p; /* if (p == 0) { IoState_error_(IOSTATE, m, "DynLib error marshalling argument (%i) to call '%s'.", n + 1, CSTRING(callName)); // FIXME this can leak memory. io_free(params); return IONIL(self); } */ } #if 0 printf("calling %s with %i arguments\n", CSTRING(IoMessage_locals_symbolArgAt_(m, locals, 0)), IoMessage_argCount(m) - 1); #endif IoState_pushCollectorPause(IOSTATE); if (isVoid) { IoDynLib_rawVoidCall(f, IoMessage_argCount(m), params); } else { rc = (int)IoDynLib_rawNonVoidCall(f, IoMessage_argCount(m), params); } IoState_popCollectorPause(IOSTATE); for (n = 0; n < IoMessage_argCount(m) - 1; n ++) { IoObject *arg = IoMessage_locals_valueArgAt_(m, locals, n + 1); demarshal(self, arg, params[n]); } io_free(params); return isVoid ? IONIL(self) : IONUMBER(rc); }