Problem interfacing with external C code - wxwidgets 3.0.2 unicode build Topic is solved

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
Post Reply
Tony0945
Experienced Solver
Experienced Solver
Posts: 96
Joined: Wed Oct 21, 2009 4:02 pm

Problem interfacing with external C code - wxwidgets 3.0.2 unicode build

Post by Tony0945 » Sun Jul 31, 2016 3:38 am

Code: Select all

#include <wx/wx.h>


// #include "globals.h"
extern "C" {
            char * Null_C_String;
            int set_tuner(char *channel, int adapter, int frontend, int demux, char *confname);
            };

int TuneChannel(wxString * channel, int adapter, int frontend,int demux, wxString  config_filename)
{
    if (config_filename.IsEmpty())
        return set_tuner(channel->mb_str(),adapter,frontend,demux, Null_C_String);
    else
        return set_tuner(channel->mb_str(),adapter,frontend,demux, (config_filename.ToAscii()).mb_str());
}


// components of the favorites table
wxArrayInt FavPriority,FavChannelID,FavStop,FavStart;
wxArrayString FavTitle;
with resulting error messages:
[email protected] ~/oregano/src $ make globals.o
g++ -DHAVE_CONFIG_H -I. -I.. -g -O2 -march=native -O2 -pipe -I/usr/lib64/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread -MT globals.o -MD -MP -MF .deps/globals.Tpo -c -o globals.o globals.cpp
globals.cpp: In function 'int TuneChannel(wxString*, int, int, int, wxString)':
globals.cpp:13:76: error: invalid user-defined conversion from 'const wxScopedCharBuffer {aka const wxScopedCharTypeBuffer<char>}' to 'char*' [-fpermissive]
return set_tuner(channel->mb_str(),adapter,frontend,demux, Null_C_String);
^
In file included from /usr/include/wx-3.0/wx/strconv.h:17:0,
from /usr/include/wx-3.0/wx/strvararg.h:20,
from /usr/include/wx-3.0/wx/string.h:46,
from /usr/include/wx-3.0/wx/memory.h:15,
from /usr/include/wx-3.0/wx/object.h:19,
from /usr/include/wx-3.0/wx/wx.h:15,
from globals.cpp:1:
/usr/include/wx-3.0/wx/buffer.h:157:5: note: candidate is: wxScopedCharTypeBuffer<T>::operator const CharType*() const [with T = char; wxScopedCharTypeBuffer<T>::CharType = char] <near match>
operator const CharType *() const { return data(); }
^
/usr/include/wx-3.0/wx/buffer.h:157:5: note: no known conversion from 'const CharType* {aka const char*}' to 'char*'
globals.cpp:15:91: error: 'const wxScopedCharBuffer' has no member named 'mb_str'
return set_tuner(channel->mb_str(),adapter,frontend,demux, (config_filename.ToAscii()).mb_str());
^
Makefile:436: recipe for target 'globals.o' failed
make: *** [globals.o] Error 1


I don't understand why I have an error in the first call. I probably screwed up syntax in the second call, but the first call has no conversion. it calls an external C function passing an external C variable.

New Pagodi
Super wx Problem Solver
Super wx Problem Solver
Posts: 327
Joined: Tue Jun 20, 2006 6:47 pm
Contact:

Re: Problem interfacing with external C code - wxwidgets 3.0.2 unicode build

Post by New Pagodi » Sun Jul 31, 2016 8:29 am

wxString can be implicitly cast to const char* but not to char*. You can either redefine the set_tuner function to take a const char* as the first paramenter or, if your sure the sure the string is not changed, use a const_cast to explicitly convert the wxString.

Tony0945
Experienced Solver
Experienced Solver
Posts: 96
Joined: Wed Oct 21, 2009 4:02 pm

Re: Problem interfacing with external C code - wxwidgets 3.0.2 unicode build

Post by Tony0945 » Sun Jul 31, 2016 10:10 am

Thank You! I have phonied up the C prototype as, in fact, the strings are not modified in the C function.

Code: Select all

#include <wx/wx.h>


// #include "globals.h"
extern "C" {
            char * Null_C_String;
            int set_tuner(const char *channel, int adapter, int frontend, int demux, const char *confname);
            };

int TuneChannel(wxString * channel, int adapter, int frontend,int demux, wxString  config_filename)
{
    const char *ptr1 = (const char *)channel->c_str();
    const char *ptr2 = (const char *)config_filename.c_str();
    if (config_filename.IsEmpty())
        return set_tuner(ptr1,adapter,frontend,demux, Null_C_String);
    else
        return set_tuner(ptr1,adapter,frontend,demux, ptr2);
}


// components of the favorites table
wxArrayInt FavPriority,FavChannelID,FavStop,FavStart;
wxArrayString FavTitle;


User avatar
doublemax
Moderator
Moderator
Posts: 14630
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problem interfacing with external C code - wxwidgets 3.0.2 unicode build

Post by doublemax » Sun Jul 31, 2016 11:55 am

Code: Select all

const char *ptr1 = (const char *)channel->c_str();
You can't do it this way. The pointer will be invalid in the next line because it points to a temporary object.
Put the "(const char *)channel->c_str()" inside the function call (for both pointers).
Use the source, Luke!

Tony0945
Experienced Solver
Experienced Solver
Posts: 96
Joined: Wed Oct 21, 2009 4:02 pm

Re: Problem interfacing with external C code - wxwidgets 3.0.2 unicode build

Post by Tony0945 » Sun Jul 31, 2016 9:36 pm

Seemed to be work, but probably only because the compiler optimized the two steps into one.

I split the C++ functions into a base and overloaded version. That way, each is one line and no test is necessary. The programmer makes the choice by which function he uses.

Code: Select all

//header
extern int TuneChannel(wxString * channel, int adapter=0, int frontend=0,int demux=0 );
extern int TuneChannel(wxString * channel, wxString * config_file, int adapter=0, int frontend=0,int demux=0 );

//source
int TuneChannel(wxString * channel, wxString *config_filename, int adapter, int frontend, int demux)
{
    return set_tuner( (const char *)channel->c_str(),adapter,frontend,demux, (const char *)config_filename->c_str());
}

int TuneChannel(wxString * channel, int adapter, int frontend,int demux)
{
    return set_tuner((const char *)channel->c_str(),adapter,frontend,demux, (const char *)0);
}
I guess the extern's are not necessary, either. Old C habits die hard.

Thank you for warning me of the land mine in my code.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2242
Joined: Sun Jan 03, 2010 5:45 pm

Re: Problem interfacing with external C code - wxwidgets 3.0.2 unicode build

Post by PB » Sun Jul 31, 2016 9:59 pm

Tony0945 wrote:Old C habits die hard.
Also in C++, you would generally declare [in] wxString parameters as

Code: Select all

const wxString& param
instead of

Code: Select all

wxString* param
One usually uses pointers instead of const references in cases where you can pass NULLs, with the parameter being optional.

Post Reply