By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,932 Members | 1,455 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,932 IT Pros & Developers. It's quick & easy.

Linkage Problem Question

P: n/a
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
Oct 4 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Im************@hotmail.com kirjutas:
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()
This should be:

inline 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 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;
}

>
If you forget to define ReadWrite(), then C++ Compiler succeeds to
compile, but it fails to link.
This is a good thing, isn't it?
Please suggest the best practice how .lib and .dll can call
ReadWrite() in main.cpp source code.
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!

hth
Paavo

Oct 4 '08 #2

P: n/a
On Oct 4, 7:10*am, Paavo Helde <nob...@ebi.eewrote:
Immortal_Ne...@hotmail.com kirjutas:


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()

This should be:

inline 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 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;

}
If you forget to define ReadWrite(), then C++ Compiler succeeds to
compile, but it fails to link. *

This is a good thing, isn't it?
Please suggest the best practice how .lib and .dll can call
ReadWrite() in main.cpp source code.

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
Oct 5 '08 #3

P: n/a
Im************@hotmail.com kirjutas:
On Oct 4, 7:10*am, Paavo Helde <nob...@ebi.eewrote:
>Immortal_Ne...@hotmail.com kirjutas:


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 th
e
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()

This should be:

inline 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 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;

}
If you forget to define ReadWrite(), then C++ Compiler succeeds to
compile, but it fails to link. *

This is a good thing, isn't it?
Please suggest the best practice how .lib and .dll can call
ReadWrite() in main.cpp source code.

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.
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);
}

Oct 6 '08 #4

P: n/a
On Oct 6, 11:02*am, Paavo Helde <nob...@ebi.eewrote:
Immortal_Ne...@hotmail.com kirjutas:


On Oct 4, 7:10*am, Paavo Helde <nob...@ebi.eewrote:
Immortal_Ne...@hotmail.com kirjutas:
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 th
e
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()
This should be:
inline 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 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;
}
If you forget to define ReadWrite(), then C++ Compiler succeeds to
compile, but it fails to link. *
This is a good thing, isn't it?
Please suggest the best practice how .lib and .dll can call
ReadWrite() in main.cpp source code.
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.

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 "
Oct 6 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.