Dynamic function loading


Sometimes, you may find it necessary to use an Win32 API function not included in the SDK wrappers. You may be able to compile source containing the function, but the link stage will fail because the symbol will be undefined and you cannot link directly against the MainWin library containing the function's symbol.
You can, however, create your own wrapper to resolve the linker dependency and dynamically load the symbol from its MainWin library. Suppose you need to use the following function:
[C++]
HRESULT NiftyFunction(HINSTANCE hInst, LPSTR lpName, DWORD dwValue);
In order to create a wrapper, you'll need to do two things. First, add the following line in your code so that is appears before NiftyFunction's prototype:
[C++]
          #define NiftyFunction NiftyFunction__ESRI_USER_WRAPPER
Second, add the following code to any .cpp file (or make sure it appears in only one compilation unit [.o]):
[C++]
          #include ESRIDynFcn(HRESULT , NiftyFunction , (HINSTANCE hInst, LPSTR lpName,
  DWORD dwValue), (hInst, lpName, dwValue), libarcsdk_rt.so)
The above #include directive can be located elsewhere. The ESRIDynFcn macro will be expanded by the compiler into a complete wrapper function. The arguments, in order, are:
  • the function's return type (can be void)
  • the function's name
  • the complete argument list, including argument types and argument names
  • the name-only argument list
  • the library in which the function's symbol is located (this can almost always be resolved through libarcsd_rt.so)
This dynamic loading scheme is not limited to the Win32 API. It can be used to load any symbol from any library at runtime.

C++ Symbol Conflicts

Because the C++ API's dynamic function loading uses C-style macros, symbol conflicts may arise between C API functions and C++ class methods. If, for example, you have a class with a method named ExistingAPIFunc, linking your code may produce the following error:
    Undefined                       first referenced
     symbol                             in file
    void MyClass::ExistingAPIFunc__ESRI_WRAPPER() MyProgram.o
    ld: fatal: Symbol referencing errors. No output written to MyProgram
In this case, you will need to add:
[C++]
          #undef ExistingAPIFunc
to your code immediately after including ArcSDK.h. If you need to use ExistingAPIFunc (the C function), you can call it using ExistingAPIFunc__ESRI_WRAPPER or by restricting its use to a separate compilation unit containing and including no references to MyClass.