[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Calling third party C library functions from C++

Dhillon

12/15/2008 2:10:00 PM

Hello All,

I have searched internet and also posts on this group. None of the
suggestions have worked in my case.
I am having linker issues when I try to use a C funtion in C++ code.


Though I have declared that C function as extern "C" c_func(......)
in my .cpp file.

Also this c_func takes argument as (void*, void (cpp_func*)(int,
void*, unsigned long), void*)

Here cpp_func is a pointer to a function in my .cpp file(not a member
function) where I am calling this c_func

To avoid name mangling by C++ compiler for the function to which
cpp_func points to I have also declared this

functions as extren "C" cpp_function_pointed_to (....) in my .h file
so that c_func is able to use this callback function which is defined
in my C++ file.

Please correct me where I am going wrong.

Despite doing all this, When I try to build my project I fail at
linker stage where linker complians about undefined funtion c_func
referred from function_pointed_by defined in my .cpp file

I am using CodeWarrior IDE for my development.

Thanks in advance,
MD
5 Answers

Victor Bazarov

12/15/2008 2:20:00 PM

0

Dhillon wrote:
> I have searched internet and also posts on this group. None of the
> suggestions have worked in my case.
> I am having linker issues when I try to use a C funtion in C++ code.
>
>
> Though I have declared that C function as extern "C" c_func(......)
> in my .cpp file.
>
> Also this c_func takes argument as (void*, void (cpp_func*)(int,
> void*, unsigned long), void*)

This looks like a declaration of the arguments. If that's so, then your
"cpp_func" has to be a part of the declaration (since it precedes the
asterisk), like a modifier or a specifier. Is it? If it isn't, do not
put it here. Just say that your 'c_func' has the following declaration:

extern "C" <return_value_type> c_func(void*, void (*)(int,void*,unsigned
long), void*);

If that's so, then I suspect you might need to add something in front of
the asterisk in the parentheses like so:

... c_func(void*, void (extern "C" *)(int,void* ...
// ^^^^^^^^^^

>
> Here cpp_func is a pointer to a function in my .cpp file(not a member
> function) where I am calling this c_func

Huh?

> To avoid name mangling by C++ compiler for the function to which
> cpp_func points to I have also declared this
>
> functions as extren "C" cpp_function_pointed_to (....) in my .h file
> so that c_func is able to use this callback function which is defined
> in my C++ file.
>
> Please correct me where I am going wrong.

Read the FAQ 5.8 and follow its recommendations.

> Despite doing all this, When I try to build my project I fail at
> linker stage where linker complians about undefined funtion c_func
> referred from function_pointed_by defined in my .cpp file
>
> I am using CodeWarrior IDE for my development.

That's only relevant if you need help with your IDE (which you can't
really get here, since this is a tool-neutral newsgroup).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Dhillon

12/15/2008 2:52:00 PM

0

On Dec 15, 9:19 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Dhillon wrote:
> > I have searched internet and also posts on this group. None of the
> > suggestions have worked in my case.
> > I am having linker issues when I try to use a C funtion in C++ code.
>
> > Though I have declared that C function as  extern "C" c_func(......)
> > in my .cpp file.
>
> > Also this c_func takes argument as (void*, void (cpp_func*)(int,
> > void*, unsigned long), void*)
>
> This looks like a declaration of the arguments.  If that's so, then your
> "cpp_func" has to be a part of the declaration (since it precedes the
> asterisk), like a modifier or a specifier.  Is it?  If it isn't, do not
> put it here.  Just say that your 'c_func' has the following declaration:
>
> extern "C" <return_value_type> c_func(void*, void (*)(int,void*,unsigned
> long), void*);
>
> If that's so, then I suspect you might need to add something in front of
> the asterisk in the parentheses like so:
>
>     ... c_func(void*, void (extern "C" *)(int,void* ...
> //                         ^^^^^^^^^^
>
>
>
> > Here cpp_func is a pointer to a function in my .cpp file(not a member
> > function) where I am calling this c_func
>
> Huh?
>
> > To avoid name mangling by C++ compiler for the function to which
> > cpp_func points to I have also declared this
>
> > functions as extren "C"  cpp_function_pointed_to (....) in my .h file
> > so that c_func is able to use this callback function which is defined
> > in my C++ file.
>
> > Please correct me where I am going wrong.
>
> Read the FAQ 5.8 and follow its recommendations.
>
> > Despite doing all this, When I try to build my project I fail at
> > linker stage where linker complians about undefined funtion c_func
> > referred from function_pointed_by defined in my .cpp file
>
> > I am using CodeWarrior IDE for my development.
>
> That's only relevant if you need help with your IDE (which you can't
> really get here, since this is a tool-neutral newsgroup).
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask

Hi,
Thanks for your reply.
I am using c/C== compilar from Codewarrior IDE version 4.2.7
Searched the whole user guide but they have not specified the compilar
version number being used.

Following may explain more what I am trying to do.

-----------------------------------------------------------------------
my_cpp_file_1.h
-----------------------------------------------------------------------

extern "C" func_pointed_to (
uint_32 node,
uint_32 node_mask,
void* data,
void* data_mask
);


-----------------------------------------------------------------------
my_cpp_file_1.cpp
-----------------------------------------------------------------------
#include my_cpp_file_1.h

extern "C" void c_func(
void* root,
uint_32 (* cpp_func)(uint_32, uint_32, void*, void*),
void* data
);

uint_3 func_pointed_to (
uint_32 node,
uint_32 node_mask,
void* data,
void* data_mask
)
{
......................
........................
return false;

} /* Endbody */

uint_32 my_cpp_func(
uint_32 node,
uint_32 node_mask,
void* data,
void* data_mask
)
{
..........................
............................

c_func(pointer_1, &func_pointed_to, pointer_2);
.............................
}

Victor Bazarov

12/15/2008 4:17:00 PM

0

Dhillon wrote:
> On Dec 15, 9:19 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> Dhillon wrote:
>>> I have searched internet and also posts on this group. None of the
>>> suggestions have worked in my case.
>>> I am having linker issues when I try to use a C funtion in C++ code.
>>> Though I have declared that C function as extern "C" c_func(......)
>>> in my .cpp file.
>>> Also this c_func takes argument as (void*, void (cpp_func*)(int,
>>> void*, unsigned long), void*)
>> This looks like a declaration of the arguments. If that's so, then your
>> "cpp_func" has to be a part of the declaration (since it precedes the
>> asterisk), like a modifier or a specifier. Is it? If it isn't, do not
>> put it here. Just say that your 'c_func' has the following declaration:
>>
>> extern "C" <return_value_type> c_func(void*, void (*)(int,void*,unsigned
>> long), void*);
>>
>> If that's so, then I suspect you might need to add something in front of
>> the asterisk in the parentheses like so:
>>
>> ... c_func(void*, void (extern "C" *)(int,void* ...
>> // ^^^^^^^^^^
>>
>>
>>
>>> Here cpp_func is a pointer to a function in my .cpp file(not a member
>>> function) where I am calling this c_func
>> Huh?
>>
>>> To avoid name mangling by C++ compiler for the function to which
>>> cpp_func points to I have also declared this
>>> functions as extren "C" cpp_function_pointed_to (....) in my .h file
>>> so that c_func is able to use this callback function which is defined
>>> in my C++ file.
>>> Please correct me where I am going wrong.
>> Read the FAQ 5.8 and follow its recommendations.
>>
>>> Despite doing all this, When I try to build my project I fail at
>>> linker stage where linker complians about undefined funtion c_func
>>> referred from function_pointed_by defined in my .cpp file
>>> I am using CodeWarrior IDE for my development.
>> That's only relevant if you need help with your IDE (which you can't
>> really get here, since this is a tool-neutral newsgroup).
>>
>> V
>> --
>> Please remove capital 'A's when replying by e-mail
>> I do not respond to top-posted replies, please don't ask
>
> Hi,
> Thanks for your reply.
> I am using c/C== compilar from Codewarrior IDE version 4.2.7
> Searched the whole user guide but they have not specified the compilar
> version number being used.
>
> Following may explain more what I am trying to do.

May. Or may not. You've confused several concepts here, AFAICS. Let's
pick each and discuss.

First off, is your subject correct? You're trying to call a third-party
C function (one or several shouldn't matter), right? What does this
have to do with whether you're calling it from C or from C++? Probably
nothing. When you call 'printf' from your C++ code, that's exactly what
happens, you're calling a C function from C++. So, you need to declare
*that particular* funciton 'extern "C"' in your C++ module. Nothing
more, nothing less.

Now, is that all? Perhaps not. Does that C function need a pointer to
a callback function that you're providing? If so, then the callback
should also adhere to the "C" rules, and the best you can do is to
declare that C++ function as 'extern "C"' as well (so that it's going to
be callable from C).

Let's get to your code. But let's agree on some terminology first. A
_C++ function_ is a function *implemented* in C++, most likely in your
module. A _callback function_ is a function a pointer to which is passed
to another function, which in turn can call it. The two concepts are
orthogonal.

>
> -----------------------------------------------------------------------
> my_cpp_file_1.h
> -----------------------------------------------------------------------
>
> extern "C" func_pointed_to (
> uint_32 node,
> uint_32 node_mask,
> void* data,
> void* data_mask
> );

What's the role of that function? How can I (or anybody else)
understand this from your code? "func_pointed_to"? Are you going to
use it as a callback? Is it going to be called from C or from C++? Why
do you declare it 'extern "C"'?

So, is this a C++ function that you're going to make a callback to be
called from C? Then it probably correctly has the 'extern "C"'
specification. If it's not to be called from C, and it's your function,
then you probably can drop the 'extern' thing. If it's not your
function, then at least put some comment to that effect.

>
>
> -----------------------------------------------------------------------
> my_cpp_file_1.cpp
> -----------------------------------------------------------------------
> #include my_cpp_file_1.h
>
> extern "C" void c_func(
> void* root,
> uint_32 (* cpp_func)(uint_32, uint_32, void*, void*),
> void* data
> );

Is that the function from the third-party library? Do you control how
it's declared?

>
> uint_3 func_pointed_to (

I am guessing it's

uint_32 func_pointed_to (

and it's the implementation of the function you just declared in
'my_cpp_file_1.h'. If so, then both declarations *must match*, i.e.
this declaration/definition *must* start with 'extern "C"' as well.

> uint_32 node,
> uint_32 node_mask,
> void* data,
> void* data_mask
> )
> {
> ......................
> ........................
> return false;
>
> } /* Endbody */
>
> uint_32 my_cpp_func(
> uint_32 node,
> uint_32 node_mask,
> void* data,
> void* data_mask
> )

Are all those things ('my_cpp_func', the arguments) important? If not,
drop them from your [future] posts. Given this particular form, they
just muddy the waters. You could simply say

int main()

here.

> {
> ..........................
> ............................
>
> c_func(pointer_1, &func_pointed_to, pointer_2);
> .............................
> }
>

So, if my guesses are correct, you should have this:

--------------------------- file "3rdpartylib.c"
int foo(int a, void (*pf)(int))
{
pf(a);
return 42;
}
--------------------------- file "3rdpartylib.h"
#ifdef __cplusplus
extern "C"
#endif
int foo(int a, void (*pf)(int));
--------------------------- file "myprogram.cpp"
#include "3rdpartylib.h"
#include <iostream>
#inlcude <ostream>

extern "C" void my_cpp_callback(int a)
{
std::cout << "(in my_cpp_callback, a == " << a << ")";
}

int main()
{
std::cout << "got from C: " << foo(666, my_cpp_callback);
std::cout << std::endl;
}
--------------------------------------------------------

This is a complete program. You should be able to compile the two
translation units from it into separate modules (one .lib or .a and the
other into the executable), and have it print something like

got from C: (in my_cpp_callback, a == 666) 42

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

James Kanze

12/16/2008 10:15:00 AM

0

On Dec 15, 3:19 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Dhillon wrote:
> > I have searched internet and also posts on this group. None
> > of the suggestions have worked in my case.
> > I am having linker issues when I try to use a C funtion in
> > C++ code.

> > Though I have declared that C function as extern "C" c_func(......)
> > in my .cpp file.

> > Also this c_func takes argument as (void*, void
> > (cpp_func*)(int, void*, unsigned long), void*)

> This looks like a declaration of the arguments. If that's so,
> then your "cpp_func" has to be a part of the declaration
> (since it precedes the asterisk), like a modifier or a
> specifier. Is it? If it isn't, do not put it here. Just say
> that your 'c_func' has the following declaration:

> extern "C" <return_value_type> c_func(void*, void
> (*)(int,void*,unsigned long), void*);

> If that's so, then I suspect you might need to add something
> in front of the asterisk in the parentheses like so:

> ... c_func(void*, void (extern "C" *)(int,void* ...
> // ^^^^^^^^^^

The ``extern "C"'' is valid for the entire declaration,
including the function pointer argument; ``extern "C"'' where
you want to put it isn't legal.

If you need to declare a pointer to a function argument as
``extern "C"'', without declaring the function ``extern "C"'',
you have to use a typedef:

extern "C" { typedef void (*PtrToCFnc)() ; }
void f( PtrToCFnc ) ;

> > Here cpp_func is a pointer to a function in my .cpp file(not
> > a member function) where I am calling this c_func

> Huh?

He lost me too. A small example would doubtlessly clarify
things.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Dhillon

12/17/2008 7:44:00 PM

0

On Dec 16, 5:15 am, James Kanze <james.ka...@gmail.com> wrote:
> On Dec 15, 3:19 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>
>
>
>
>
> > Dhillon wrote:
> > > I have searched internet and also posts on this group. None
> > > of the suggestions have worked in my case.
> > > I am having linker issues when I try to use a C funtion in
> > > C++ code.
> > > Though I have declared that C function as  extern "C" c_func(......)
> > > in my .cpp file.
> > > Also this c_func takes argument as (void*, void
> > > (cpp_func*)(int, void*, unsigned long), void*)
> > This looks like a declaration of the arguments.  If that's so,
> > then your "cpp_func" has to be a part of the declaration
> > (since it precedes the asterisk), like a modifier or a
> > specifier.  Is it?  If it isn't, do not put it here.  Just say
> > that your 'c_func' has the following declaration:
> > extern "C" <return_value_type> c_func(void*, void
> > (*)(int,void*,unsigned long), void*);
> > If that's so, then I suspect you might need to add something
> > in front of the asterisk in the parentheses like so:
> >     ... c_func(void*, void (extern "C" *)(int,void* ...
> > //                         ^^^^^^^^^^
>
> The ``extern "C"'' is valid for the entire declaration,
> including the function pointer argument; ``extern "C"'' where
> you want to put it isn't legal.
>
> If you need to declare a pointer to a function argument as
> ``extern "C"'', without declaring the function ``extern "C"'',
> you have to use a typedef:
>
>     extern "C" { typedef void (*PtrToCFnc)() ; }
>     void f( PtrToCFnc ) ;
>
> > > Here cpp_func is a pointer to a function in my .cpp file(not
> > > a member function) where I am calling this c_func
> > Huh?
>
> He lost me too.  A small example would doubtlessly clarify
> things.
>
> --
> James Kanze (GABI Software)             email:james.ka...@gmail.com
> Conseils en informatique orientée objet/
>                    Beratung in objektorientierter Datenverarbeitung
> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -
>
> - Show quoted text -

Thanks for your comments. Victor's second post cleared all the doubts.
I am able to link the code now.
Appreciate your input.