1

Stupid question that I'm sure is some bit of syntax that's not right. How do I get dlsym to work with a function that returns a value? I'm getting the error 'invalid conversion of void* to LSError (*)()' in the following code - trying to get the compile the linux lightscribe sample program hoping that I can link it against the OSX dylib (why the hell won't HP release an actual Cocoa SDK? LS has only been around for what? 6 or 7 years now?):

void* LSHandle = dlopen("liblightscribe.1.dylib", RTLD_LOCAL|RTLD_LAZY);
    if (LSHandle) {
        LSError (*LS_DiscPrinter_ReleaseExclusiveUse)() = dlsym(LSHandle, "LS_DiscPrinter_ReleaseExclusiveUse");

..
lsError = LS_DiscPrinter_ReleaseExclusiveUse( pDiscPrinter);
Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
Jim Witte
  • 100
  • 1
  • 10
  • 1
    I found this page http://www.trilithium.com/johan/2004/12/problem-with-dlsym/ and that seems to address a problem like this about having to cast a void* to a function pointer. Uugh.. – Jim Witte Mar 06 '11 at 04:34
  • I found a construction that worked. After opening the file with dlopen, I have a set of lines as such: LSError (*LS_DiscPrinter_ReleaseExclusiveUse)(LS_DiscPrinterHandle); LS_DiscPrinter_ReleaseExclusiveUse = (LSError (*)(void*)) dlsym(LSHandle, "LS_DiscPrinter_ReleaseExclusiveUse"); which is rather unwieldy. xCode didn't like using the typedef as is on the second page I found - which I don't understand as 'extern "C" typedef XML_Parser parsercreate_t(const XML_Char*);' does't mention the return type of XML_ParserStruct at all. – Jim Witte Mar 06 '11 at 06:08

1 Answers1

3

The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.

The “recommended” way to use dlsym is:

 LSError (*LS_DiscPrinter_ReleaseExclusiveUse)(LS_DiscPrinterHandle);

 *(void **)&LS_DiscPrinter_ReleaseExclusiveUse = dlsym("LS_DiscPrinter_ReleaseExclusiveUse");

Read the rationale and example on the POSIX page for dlsym for more information.

dreamlax
  • 93,976
  • 29
  • 161
  • 209