I am building a C++ project on my Mac system. I have static library libA.a which is linked to a Mac framework (B.framework). I am dynamically linking B.framework with my executable exe.
There is a static member defined in a class defined in libA.a
class MyClass {
static MyType* myVar;
public:
print() {
//prints address of myVar(&myVar) value
}
};
I observed that at runtime when I call the print() method via code in B.framework and via code in exe, both print different values of &myVar.
It looks like exe has a separate copy of myVar. What I expected and wanted to achieve is to have a single copy of myVar? Is there a way to achieve this?
Related
I have a library project which contains opaque structures of different types.For example:
OpaqueTypes.h
typedef struct FooObject_t *FooObjectPtr
FooObjectPtr CreateFooObject();
OpaqueTypes.cpp
struct FooObject_t
{
uint32_t id;
uint32_t someProp;
};
FooObjectPtr CreateFooObject()
{
FooObjectPtr fooPtr = nullptr;
//Create new instance and cache it
return fooPtr;
}
I compile this code as a static library.Another project is an executable which links with that library. It has no access to definition of FooObject_t . Yet,when I run the application in debug mode, I can see all the members of FooObject_t pointer. The only setup which completely hides the internals of FooObject_t ,even from debugger, is if I compile OpaqueTypes lib as DLL.
I have two questions:
How debugger can see the implementation details of FooObject_t in main application when OpaqueTypes is compiled statically with definition hidden, but it can't see it when the lib is DLL?
Is it possible to hide the implementation details completely when working with static lib?
I am using Visual Studio 2019
It is possible because the static lib, compiled with debug on, holds the references to the source files with full object description.
I suppose that the full object is visible debugging functions inside the library, it shoul be opaque when debugging exe functions.
Try to debug using a library compiled without debug info, that is the one you are supposed to supply, and the definition should result opaque.
When using the DLL the pseudo-lib used for the dynamic linking shouldn't contain debug info, although when inside, if DLL has been compiled with debug on, you should still able to see the structure.
Last, things depend also on the compiler used, on the debugger, on which directory are used to run the test, etc...
Here’s the code:
struct S
{
S()
{
__debugbreak();
}
};
static const S g_s;
Obviously, I want some code to run at startup.
This only works for some source files, that have symbols referenced by outside code. For source files in a static library that don’t have any symbols referenced from outside, looks like the compiler or linker drop the complete compilation unit, so the global object is not constructed.
Is there a way to force construction of static objects, or otherwise force running of the code at startup?
I’ve double checked compilation settings for these source files, they are identical, and they are in the same static library project.
The static library is used by a DLL. Global objects are expected to be constructed before DLL_PROCESS_ATTACH call.
You will need to link "everything" from this library using linker options such as
-Wl--whole-archive -lmylib -Wl--no-whole-archive (gcc)
or
/INCLUDE symbol (vc)
or
/WHOLEARCHIVE:mylib (vc)
However relying on dynamic initialization stage and / or making assumptions about state of global objects during program startup / dll loading makes your program doomed. So you should consider explicit initialization instead.
I have a similar setup as described below:
Project A
Windows DLL
Depends on Project B
Project B
Compiled as static library
Now, if a global function, e.g. createNewFoo is compiled in Project B, it is never exported into the final DLL, although it is declared with dllexport and the final application uses it as dllimport:
namespace example
{
class __declspec(dllexport) Foo
{
Foo();
};
__declspec(dllexport) Foo* createNewFoo();
}
}
Note that, the class Foo is always exported into the final DLL, its only global or static functions that are somehow discarded.
Furthermore, note that the same global function is always exported if it is compiled in Project A instead of Project B.
Is there any setting in Visual Studio 2010 that allows exporting of global or static functions from dependent projects? or this is a limitation of the tools?
Using a static library is a great way to reuse code. Rather than re-implementing the same routines in every app that requires the functionality, you write them one time in a static library and then reference it from the apps. Code linked from a static library becomes part of your app—you don’t have to install another file to use the code.
As you case, Lib B's function is linked and become a part of DLL A, if you want to export these function in DLL A, you should explicitly dllexport function in DLL A, and in function body, you can call Lib B's function to reuse code.
When I have an abstract base class foo, defined in libX.a
class foo {
virtual void bar() = 0;
};
... and a derived class foo_impl, defined in libY.a
class foo_impl : public foo {
void bar() { /* do something */ }
};
... and use both libraries to link a program -lX -lY
int main() {
foo* my_foo = receive_a_foo_from_somewhere();
my_foo->bar();
}
Then
how can I force the linker to actually link the symbol referring to foo_impl::bar()?
does objdump -t program list foo_impl::bar() when it is correctly linked?
EDIT: to clarify, I am using linux with gcc or clang
EDIT 2: had missed virtual for bar()
EDIT 4: I apologize for missing clarity. The question should have been "how can I force the linker to actually include foo_impl::bar() in the executable so it can be resolved at runtime?"
Since the bar method is defined as virtual, there is no need of static linking. The linking will be done dynamically at runtime based on the object type to which the *my_foo refers to. Regardless of whether it's defined in libX.a or libY.a.
Answer to you question how to force the linker to link the symbol referring to foo_impl::bar()?
You can't force the linker to link to particular implementation. The linking will happen based on which object address you got from receive_a_foo_from_somewhere().
Obviously the implementation should be linked to your exe. If it is not available it will definitely fail. But you can't force linker to link particular implementation,
It appears there are at least two ways to get the linker to include foo_impl::bar() functionality in the executable:
With gcc, one can use -Wl,--whole-archive to link an entire static library - no matter what.
As Captain Obvlious pointed out, when foo_impl is used in the program, it's virtual functions are tagged as having been used and are thus included in the executable. This could also be an otherwise useless static dummy foo_impl object.
gph is a singleton class with no getInstance method
class gph
{
public:
static void newfun();
static void newfun1();
//...//
private:
gph();
};
This class gets build into a static library
Now I have a Dll from where I need to access the static function . So class A is a part of a Dll
I have a C++ member function say
void A:: fun()
{
gph::newfun() ; //accessing a static function : gives linker errors
}
On the other hand if I make fun() as static it doesnt give me any linker errors . But I do not want to make fun() as static
Most of what I work on deals with statically linked libraries, so this answer may not apply, but may clue you in to the problem. So based on that and what I'm looking at right now, my first thought would be to check that in the dll you're building, you've included the static library.
An unresolved symbol usually means that either the signature doesn't match or you're not including the necessary library. It varies from compiler to compiler, but most make you specify the library directory (sometimes denoted by -L in a command line) and the actual library to be linked in (sometimes denoted by -l).
Since I don't use DLL's that much, my understanding of them is similar to building an executable. If you use dynamic linking when you build, the path of the libraries you are linking to are embedded in your executable, so your executable size is smaller, but is dependent on the library path they are linked to on not moving.
So when you're building your DLL, make sure you've compiled the cpp for class gph and created a static library for it. Then when you use it in class A, you include the header and link in the library.
I think it is the calling convention issue.
Please try the following code:
class gph
{
public:
static void __cdecl newfun();
//...//
};