0

I'm currently trying to port an old owl-c++-builder-projekt to use XE2 and owlnext. In the old file, I could simply call a line

(FARPROC)LP_I2COpen = GetProcAddress(Hi_I2C, "I2COpen");

While LP_I2Open is defined with

#ifdef WIN32
#define CALLING_CONVENTION  __stdcall
#else
#define CALLING_CONVENTION  far pascal
#endif

int CALLING_CONVENTION (*LP_I2COpen)(HWND hndl,HINSTANCE hInstance, struct I2C_PROP far *ps);

#ifdef _WIN64
typedef INT_PTR (FAR WINAPI *FARPROC)();
#else
typedef int (FAR WINAPI *FARPROC)();
#endif

WINBASEAPI FARPROC WINAPI GetProcAddress(... 

Those code-blocks are actually from multiple files. I thought this order would be intuitive.

Now I have some difficulties to rewrite this as needed. I understand, that now the left side is understood as a converting-method giving a value back, but can't be assigned to a specific value, so a "L-Value expected"-error is thrown. However, I don't quite know how to convert the FARPROC into something that would fit into LP_I2COpen... Trying without any convertions throws this error:

[BCC32 Fehler] Dio.cpp(2906): E2034 Konvertierung von 'int (__stdcall *)()' nach 'int (__stdcall *)(HWND__ *,HINSTANCE__ *,I2C_PROP *)' nicht möglich

So, does anybody know which mistakes I'm doing with this line?

(FARPROC)LP_I2COpen = GetProcAddress(Hi_I2C, "I2COpen");

Regards, Julian

Steven Carlson
  • 925
  • 1
  • 10
  • 25
Julian
  • 493
  • 4
  • 22

1 Answers1

2

Casting l-values is invalid, and AFAIK it has always been invalid, although some compilers accepted it. Technically, you create a temporary of type FARPROC which then gets assigned the result of GetProcAddress() before being discarded. The correct way looks like this:

// function type alias
typedef int CALLINGCONVENTION I2COpenFn(HWND, HINSTANCE, I2C_PROP*);
// read and convert function pointer
I2COpenFn* LP_I2COpen = (I2COpenFn*)GetProcAddress(Hi_I2C, "I2COpen");

Note that things like "far" are obsolete. Also note that this C-style cast is ugly, but you don't have any type safety anyway and it's isolated to a restricted amount of code. If you can though, use proper linking instead of loading the DLL at runtime.

doomster
  • 171
  • 2
  • Thank you very much! Well, the program was designed around '95, so there may be some obsolete things... it has also become very big, so rewriting is worth serieously thinking even with obsolete methods^^ The Code you sent me is working very well so far! – Julian Apr 19 '13 at 12:07
  • Just for the record: Remy Lebeau changed the syntax in above code from a function type to a function pointer type, which makes it IMHO harder to read and hides where you are actually using pointers. I just reverted that change. Technically, there is nothing wrong with either variant. – doomster May 14 '13 at 09:26