function that returns value from dlsym()?
Asked Answered
L

1

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);
Lavonna answered 6/3, 2011 at 3:29 Comment(2)
I found this page 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..Lavonna
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.Lavonna
S
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.

Soda answered 6/3, 2011 at 20:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.