Find the answer to your Linux question:
Results 1 to 6 of 6
Good Day Everyone, I am stucked with my project here. I have our own C written program code which is communicating with a third party C++ written program code to ...
  1. #1
    Just Joined!
    Join Date
    Dec 2009
    Posts
    4

    Calling cpp member function from c code is not really executed

    Good Day Everyone,

    I am stucked with my project here.

    I have our own C written program code which is communicating with a third party C++ written program code to run a moving device.

    We have successfully communicated with the third party code with wrapper functions.

    Now, we tried to run some functions to move the device. I think it is better for me to attach the related code first.

    pro.c (The source code we used to run the device)
    Code:
    #include <stdio.h>
    #include "wrapper.h" 
    
    int main ()
    {
            int  pro=0; 
    
            libInit(); 
            pro = PROconnectTo Device((char*) "192.168.1.87");
            printf("\nDevice Connected, Return Code = %d\n",pro); 
    
            pro = PROinitializeAndCalibrate (); 
            printf("\nDevice Initialized and Calibrated, Return Code = %d\n",pro); 
            
            pro = PROtakeTool (1); 
            printf("\nDevice Take Tool, Return Code = %d\n",pro); 
    
            PROdisconnectDevice(); 
            printf("\nDevice Disconnected\n"); 
    
            libClose(); 
    
            return pro; 
    }
    wrapper.cpp (Source code needed to communicate between C and C++ code)
    Code:
    #include <iostream>
    #include "ProjectApplication.h"
    #include "wrapper.h"
    
    ProjectApplication *w; 
    
    int    libInit (void)
    {
            w = new ProjectApplication; 
            return 0; 
    }
    
    int    PROinitializeAndCalibrate (void) 
    {
            return  w->initializeAndCalibrate(); 
    }
    
    int    PROtakeTool (unsigned int  PROtool)
    {
            unsigned int    tool; 
            tool = PROtool; 
     
            return  w->takeTool(tool); 
    }
    
    int    PROconnectToDevice (char* PROipAddr)
    {
            char* ipAddr; 
            ipAddr = PROipAddr; 
    
            return  w->connectToDevice(ipAddr); 
    }
    
    void  PROdisconnectDevice (void) 
    {
            return  w->disconnectDevice(); 
    }
    
    void  libClose (void) 
    {
            delete  w; 
            return; 
    }
    After debugging, we will run "./pro".

    The device is successfully connected and moved according to the statement in "initializeAndCalibrate ()" and return no error. Then, it turns to "takeTool (1)". The function did called successfully, we also get a return value of 0 that means no error. But, the device is not moving at all. The device then disconnect straight away and exiting the routine of "main()".

    THe execution of statement in routine "main()" pause a while after it call "initializeAndCalibrate ()" until the device finish the movement before it execute the next statement.

    After that, no more. Other statements just run so fast and it exit the program with all the statements it executed returned no error.

    We are confirmed that there is no problem with the hardware that is the device and the third party software as we test run it before using other test tool and it works well.

    We have been finding around for all possible causes for this problem but we just can't get the right one.

    Hoping there is someone that can give us some ideas.

    Thank you very much.

  2. #2
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    try declaring your functions like below:

    Code:
    extern "C" int    libInit (void);
    
    int    libInit (void)
    {
            w = new ProjectApplication; 
            return 0; 
    }
    Make mine Arch Linux

  3. #3
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Actually I have an example that I played with awhile ago. I hope you can find something of worth in it..

    Cfile.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct myans	{
    			int itssize;
    			char* thestring;
    		};
    
    extern int itssize(void *str);
    
    extern void equalit(void* lhs, struct myans theans);
    
    extern struct myans addit(void* lhs, void* rhs);
    
    extern char* getachar(void* str, int offset);
    
    extern int getsize(void* str);
    
    extern char* getstring(void* str);
    
    extern void* stringDelete(void* str);
    
    extern void* stringCreate3(const void* rhs);
    
    extern void* stringCreate2(const char* const cstring);
    
    extern void* stringCreate();
    
    int main(int argc, char**argv)
    {
    	void* me = stringCreate2("This is a test string");
    	void* you = stringCreate2("this is another");
    	void* us = stringCreate();
    
    	equalit(us,addit(me, you));
    	
    
    	fputs(getstring(me), stdout);
    	fputs("\n", stdout);
    	fputs(getstring(you), stdout);
    	fputs("\n", stdout);	
    	fputs(getstring(us), stdout);
    	fputs("\n", stdout);	
    	exit(EXIT_SUCCESS);
    }
    CPPfile.cpp
    Code:
    #include <iostream>
    
    int strlen(char* s)
    {
    	int i = 0;
    	while (s[i])
    		++i;
    	return i;
    }
    
    class xboundary
    {
    public:
    	xboundary(int size):itssize(size) {}
    	~xboundary() {}
    	void errmsg() const {std::cout<<itssize<<" is out of bounds!\n";}
    private:
    	int itssize;
    };
    
    struct myans	{
    			int itssize;
    			char* thestring;
    		};
    			
    
    class string
    {
    public:
    	string();
    	string(const char* const cstring);
    	string(const string * rhs);
    	~string();
    
    	char* getthestring() const {return thestring;}
    	int getitssize() const {return itssize;}
    	int sizeofclass() const {return sizeof(string);}
    
    	char& operator[](int offset);
    	struct myans operator+(const string * rhs);
    	string& operator=(const struct myans rhs);
    private:
    	string(int size);
    	int itssize;
    	char *thestring;
    };
    string& string::operator=(const struct myans rhs)
    {
    	itssize = rhs.itssize;
    	delete [] thestring;
    	thestring = new char[itssize + 1];
    	for (int i = 0; i < itssize; ++i)
    		thestring[i] = rhs.thestring[i];
    	thestring[itssize] = '\0';
    	delete [] rhs.thestring;//to get rid of the memory leak!!!!
    	return *this;
    }
    struct myans string::operator+(const string * rhs)
    {
    	struct myans ans;
    	ans.itssize = (itssize + rhs->itssize);
    	ans.thestring = new char[itssize + rhs->itssize + 1];
    	int i;
    
    	for (i = 0; i < itssize; ++i)
    		ans.thestring[i] = thestring[i];
    	for (int j = 0; j < rhs->itssize; ++i, ++j)
    		ans.thestring[i] = rhs->thestring[j];
    	ans.thestring[ans.itssize] = '\0';
    	
    	return ans;
    }
    char& string::operator[](int offset)
    {
    	if (offset < itssize)
    		return thestring[offset];
    	throw xboundary(offset);
    	return thestring[0];
    }
    string::string(int size)
    :itssize(size)
    {
    	thestring = new char[itssize + 1];
    	for (int i = 0; i < itssize; ++i)
    		thestring[i] = ' ';
    	thestring[itssize] = '\0'; 
    }
    string::~string()
    {
    	delete [] thestring;
    }
    string::string(const string * rhs)
    :itssize(rhs->itssize)
    {
    	thestring = new char[itssize + 1];
    	for (int i = 0; i < itssize; ++i)
    		thestring[i] = rhs->thestring[i];
    	thestring[itssize] = '\0';
    }
    string::string(const char* const cstring)
    :itssize(strlen((char*)cstring))
    {
    	thestring = new char[itssize + 1];
    	for (int i = 0; i < itssize; ++i)
    		thestring[i] = cstring[i];
    	thestring[itssize] = '\0';
    }
    string::string()
    :itssize(0)
    {
    	thestring = new char[itssize + 1];
    	for (int i = 0; i < itssize; ++i)
    		thestring[i] = ' ';
    	thestring[itssize] = '\0';
    }
    extern "C" int itssize(void *str)
    {
    	return ((string*)str)->sizeofclass();
    }
    extern "C" void equalit(void* lhs, struct myans theans)
    {
    	((string*)lhs)->operator=(theans);
    }
    extern "C" struct myans addit(void* lhs, void* rhs)
    {
    	return (((string*)lhs)->operator+((string*)rhs));
    }
    extern "C" char* getachar(void* str, int offset)
    {
    	return (char*)((string*)str)->operator[](offset);
    }
    extern "C" int getsize(void* str)
    {
    	return ((string*)str)->getitssize();
    }
    extern "C" char* getstring(void* str)
    {
    	return ((string*)str)->getthestring();
    }
    extern "C" void* stringDelete(void* str)
    {
    	delete ((string*)str);
    	return NULL;
    }
    extern "C" void* stringCreate3(const void* rhs)
    {
    	string *mystring = new string((string*)rhs);
    	return (void*)mystring;
    }
    extern "C" void* stringCreate2(const char* const cstring)
    {
    	string *mystring = new string(cstring);
    	return (void*)mystring;
    }
    
    extern "C" void* stringCreate()
    {
    	string *mystring = new string();
    	return (void*)mystring;
    }

    makefile
    Code:
    Cfile: Cfile.o CPPfile.o
    	gcc Cfile.o CPPfile.o -o Cfile -lstdc++
    
    Cfile.o: Cfile.c
    	gcc -c Cfile.c
    
    CPPfile.o: CPPfile.cpp
    	g++ -c CPPfile.cpp
    Make mine Arch Linux

  4. #4
    Just Joined!
    Join Date
    Dec 2009
    Posts
    4
    Quote Originally Posted by gerard4143 View Post
    try declaring your functions like below:

    Code:
    extern "C" int    libInit (void);
    
    int    libInit (void)
    {
            w = new ProjectApplication; 
            return 0; 
    }

    The problem did not fixed by declaring the functions as suggested.
    I am thinking is it the parameter passing is problematic.
    The program run properly for those which do not need a parameter to be passed to them.
    Only those functions that need parameters to be passed when calling is not functioning well.

    Debugging returns no error. Running the function also returns no error. The function is called successfully, it runs through the statements and returns error free.

  5. #5
    Just Joined!
    Join Date
    Dec 2009
    Posts
    4
    I tried to look through your example ode, I cannot get to understand the code correctly. It has been too high level for me.

  6. #6
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Well here's a simple example right from GCC The Complete Reference

    cppsayhello.cpp
    Code:
    #include <iostream>
    
    extern "C" void cppsayhello(char *str);
    
    void cppsayhello(char *str)
    {
    	std::cout<<str<<"\n";
    }
    c2cpp.c
    Code:
    int main(int argc, char**argv)
    {
    	cppsayhello("Hello from C to c++");
    	return 0;
    }
    and compile it using

    g++ -c cppsayhello.cpp -o cppsayhello.o
    gcc -c c2cpp.c -o c2cpp.o
    gcc cppsayhello.o c2cpp.o -lstdc++ -o c2cpp
    Make mine Arch Linux

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...