Ales100
Ales100

Reputation: 175

Visual Studio C++ static lib function exposing problem

I have created example of using static libraries. The goal is this functionality:

I don't understand one thing, this works only if fnStaticLibrary() is inside same project as main() and dllTestFunct().

If I create another solution that

dllTestFunct() is able to call fnStaticLibTest() and main() is unable to call fnStaticLibTest() due to linker. But I am able to call fnStaticLibTest() inside dllTestFunct().

I used dumpbin to see what functions are exported:

dumpbin /EXPORTS "C:\\path\\DllTestFunctDll.dll"

Output:

ordinal hint RVA      name
      1    0 00001000 ?dllTestFunct@@YAXXZ = ?dllTestFunct@@YAXXZ (void __cdecl DllTestFunct(void))
      2    1 00001070 ?fnStaticLibrary@@YAXXZ = ?fnStaticLibrary@@YAXXZ (void __cdecl fnStaticLibrary(void))

You can see that fnStaticLibTest() is missing inside the output.

In both static lib projects I export function by "__declspec(dllexport) ".

I assume that the problem is inside the Visual Studio. Do you know how to solve it?

Thank you in advance for your answers.

CODE (VS17 solution) LINK: https://github.com/Ales5475/StaticLibProblemExample

Upvotes: 1

Views: 836

Answers (3)

Minxin Yu - MSFT
Minxin Yu - MSFT

Reputation: 4125

Here is the snippet I did use #pragma comment successfully.

DLL:

__declspec(dllexport)   void DllTestFunct();

...
  #pragma comment(linker, "/export:fnStaticLibTest")
  void DllTestFunct() {
    fnStaticLibrary();
    fnStaticLibTest();
    printf("Hello world (Dynamic library)!\n");
    }

DLL's dependency: Header Folder:

XXX\StaticLibTest\StaticLibTest;
XXX\MainProgram\StaticLibrary;

DLL Folder:

XXX\StaticLibTest\x64\Debug;
XXX\MainProgram\x64\Debug;

DLL input:

StaticLibTest.lib;
StaticLibrary.lib

Static Lib:

  extern "C" void fnStaticLibTest();
...
extern "C" void fnStaticLibTest() {
    printf("Hello World! (Static library from another project)\n");
}

Upvotes: 0

mksteve
mksteve

Reputation: 13073

A DLL has explicit exports. Either

__declspec(dllexport)

or a .DEF file with exports. In this case, it appears that the static lib doesn't know if it is in a DLL or the EXE, so isn't decorated with declspec(dllexport) the best solution is for the .def file for the DLL to explicitly export the function.

The code in StaticLibTest.h

__declspec(dllexport) void fnStaticLibTest();

is inconsistent with the code in StaticLibTest.cpp

void fnStaticLibTest(){

This will not cause the function to be exported. In general include a file which declares a function / structure to ensure it is consistent.

The correct form is

void __declspec(dllexport) fnStaticLibTest(){

and

void __declspec(dllexport) fnStaticLibTest();

Otherwise you are adding the attribute to the void.

Upvotes: 0

mksteve
mksteve

Reputation: 13073

An object module is added from a .lib, if it is required. If the dll does not call (or reference) any item in a compilation unit (c/cpp file), it won't be added to the dll

This behavior is important for libraries, as it ensures that when linking against the C/C++ runtimes, then you don't import the whole of the libraries. Just those which are required.

In your case you have a DLL which doesn't require the test function, and a .EXE which expects the DLL to have it. There is no visible requirement for the test function when the DLL is being built.

Upvotes: 1

Related Questions