473,499 Members | 1,591 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Linkage Problem Question

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
4 1652
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
12101
by: qazmlp | last post by:
const has internal linkage in C++, but external linkage in C. Am I right ? But, linker reports multiply-defined error if the following header is included in multiple .cpp files. //...
20
3104
by: Grumble | last post by:
Hello everyone, As far as I understand, the 'inline' keyword is a hint for the compiler to consider the function in question as a candidate for inlining, yes? What happens when a function with...
7
1955
by: Generic Usenet Account | last post by:
I am implementing a library that can be linked in with C as well as C++ code. Obviously, the library API is functional, but in my implementation I am using STL. Because of this, my code is...
22
5959
by: Ian | last post by:
The title says it all. I can see the case where a function is to be called directly from C, the name mangling will stuff this up. But I can't see a reason why a template function can't be...
10
6135
by: Mark A. Gibbs | last post by:
I have a question about mixing C and C++. In a C++ translation unit, I want to define a function with internal linkage and C calling convention. Here's a sample of what I want to do: //...
3
6006
by: al.cpwn | last post by:
do static and inline functions or members have internal linkage? I have been reading this newsgroup on google and found conflicting ideas. Can someone please help me understand why in some places...
13
2062
by: fctk | last post by:
source: http://rm-f.net/~orange/devel/specifications/c89-draft.html#3.1.2.2 there are two passages in this paragraph i can't fully understand: 1) "If the declaration of an identifier for an...
12
1498
by: Bit byte | last post by:
I have an application written in C (actually PostgreSQL). The application appears to have been built using the Mingw set of tools (mingw compiler tools). I want to write an extension library...
1
1500
by: Kurt | last post by:
The C++ standard (in 3.5:6, p42Example) said: static int i = 0; // 1 void g() { int i; //2: i has no linkage { extern int i; //3: external linkage
6
1744
by: The Architect | last post by:
Hi, If I have the same symbol in the .data section of 2 obj files, LD gives a multiple declaration error on linking? Would like to know the reason for this (diab only issues a warning) Also...
0
7007
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7171
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7220
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7386
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5468
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4599
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3098
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
664
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
295
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.