Linkage Problem Question

I

Immortal_Nephi

You have written several global functions inside header code. Then,
you create either static library or dynamic linked library. All
global functions can be reuseable to the main() function when you
include header code.

One problem is that you have created one function. You want to place
it in the main's source code. You may not want to move it back to the
header code. The C++ Compiler will compile and link without any
problems if one function is defined outside of header code.

For example:

// Func.h header
void ReadWrite(); // function phototype

void Func1() {}
void Func2() {}
void Func3() {}

void Run()
{
Func1();
Func2();
Func3();
ReadWrite();
}

// main.cpp source code
#include "Func.h"

void ReadWrite() // define ReadWrite() here
{
}

int main()
{
Run();
return 0;
}

You can see what I mean. Func1(), Func2(),Func3(), and Run() are
always unmodified in the .lib or .dll. You want to modify ReadWrte()
in main.cpp source code.

If you forget to define ReadWrite(), then C++ Compiler succeeds to
compile, but it fails to link. The pointer to function is only the
option. You should bind ReadWrite() where Run() can executes
ReadWrite().

If you forget to define pointer to function, then C++ Compiler
succeeds to compile and link before executing program can crash with
null of pointer to function.

Please suggest the best practice how .lib and .dll can call
ReadWrite() in main.cpp source code.

Nephi
 
I

Immortal_Nephi

(e-mail address removed) kirjutas:











This should be:

inline void Run()










If I understand correctly, you want to call Run() from main.cpp and you
want that Run() would call back another function in main.cpp.

So this is essentially a callback mechanism. In C you would pass a
callback function pointer to the Run() function. In C++ you can use
templates instead, with the benefit that in addition to a plain function
you can pass a functor object holding some state, when needed.

template<typename CALLBACK>
void Run(CALLBACK callback) {
    Func1();
    Func2();
    Func3();
    callback();

}

...

int main()
{
     Run(ReadWrite);
     return 0;

}


This is a good thing, isn't it?


Your example concerned calling ReadWrite() from a function in an exported
header file. This is not inside .lib or .dll, which would be a totally
different thing.

If the function was indeed defined inside a lib or dll, the template
approach would not work (without support to template export, which is not
generally implemented). Instead I would go with defining an abstract base
class in the library header, providing a derived class with needed
overridden function in the main.cpp and passing a reference of the
derived class object to the Run() function. In my experience passing a
plain function pointer as a callback almost never suffices, the function
almost always needs some context or state from the calling site to
operate properly. And no, do not even mention global variables!


Hello, Paavo

Thanks for explanation how template works. I understand that you
can't bind ReadWrite() into Run(). Please give me example of class
code. You should define Run() in base class. Put pure virtual
ReadWrite() in the same base class. Then, base class is inside .lib
or .dll.

You write to include base class header code. You add second class to
be derived from base class. Then, you can add ReadWrite() inside
derived class. It overrides base class' ReadWrite(). You can use
base class' Run() inside main(). Run() from base class will call
ReadWrite() in derived class.

Is my saying correct? If not, please correct me.

Nephi
 
M

microcassanova

(e-mail address removed) kirjutas:










Yes, kind of, but there is actually no need to put Run() and ReadWrite()
in the same class (for the callback scheme to work, that is). I sketch a
solution where they are separate (not tested!):

lib.h:

class CallbackBase {
public:
        virtual void operator()() = 0;
        virtual ~CallbackBase() {}

};

void Run(CallbackBase& callback);

lib.cpp:

void Run(CallbackBase& callback) {
        // ...
        callback();

}

main.cpp

#include <iostream>

class Callback_A: public CallbackBase {
public:
        Callback_A(int state): state_(state) {}
        virtual void operator()() {
                std::cout << "Callback A, state=" << state_ << "\n";
        }
private:
        int state_;

};

int main() {
        Callback_A my_callback(42);
        Run(my_callback);



}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -


you can define in both lib and in main() ReadWrite(). U can force
linker to use multiple definiton . there are options for multiple
linkage. Then after linking linker uses in GCC "gnu.linker once
section " even multiple definiton presents one function gets linked
and code runs . other function will be moved to "discarded section of
linker "
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top