C++ undeclared variables - c++

A file I am using in my project has many declaration in this style:
static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
...
static VALUE
do_checksum(argc, argv, func)
int argc;
VALUE *argv;
uLong (*func)(uLong, const Bytef*, uInt);
{
...
}
While I have never written code in this way myself, I am sure it is correct. However, my compiler returns
error: 'VALUE do_checksum' redeclared as different kind of symbol
error: 'argc' was not declared in this scope
What is wrong here?
Windows 7
Code::Blocks w/ MinGW

You have yourself some old-style C parameter list declarations.
Here's a sample fix:
static VALUE do_checksum(
int argc,
VALUE *argv,
uLong (*func)(uLong, const Bytef*, uInt)
)
{
...
}
An even better fix would be to make a type alias for func like so:
using func_ptr_type = uLong (*)(uLong, const Bytef*, uInt);

Related

static_cast from 'FARPROC' is not allowed

I'm trying to get rid of a warning in my code, but I'm in way over my head here...
The original code row looks like this:
FeasaCom_Open=(tFeasaCom_Open)(GetProcAddress(static_cast<HMODULE>(hFeasaComDLL), "FeasaCom_Open"));
The warning that's thrown is:
warning: use of old-style cast
I've tried to fix this by re-writing it in this way:
FeasaCom_Open=static_cast<tFeasaCom_Open>(GetProcAddress(static_cast<HMODULE>(hFeasaComDLL), "FeasaCom_Open"));
But then I get the warning:
error: static_cast from 'FARPROC' (aka 'int (*)() __attribute__((stdcall))') to 'tFeasaCom_Open' (aka 'int (*)(int, char *) __attribute__((stdcall))') is not allowed
The definition of FeasaCom_Open is:
typedef int (__stdcall *tFeasaCom_Open)(int CommPort, char * Baudrate);
And declaration is:
tFeasaCom_Open FeasaCom_Open;
I probably don't need to tell you this, but declaration of GetProcAddress looks like this:
WINBASEAPI FARPROC WINAPI GetProcAddress (HMODULE hModule, LPCSTR lpProcName);
And FARPROC:
typedef int (WINAPI *FARPROC) ();
I've tried to fix this, but I don't really know what I'm doing here... I'm using Qt 5.9.6 with MinGW 5.3.0 32-bit, if that's any help.

Mex file building with Octave (issue with wrappers)

I am currently porting some code from Matlab to Octave. Some of the functions of the Matlab code use the Piotr's Computer Vision Matlab Toolbox (here) that includes some mex files.
In Matlab, everything is working like a charm but when I run my codes with Octave, it throws this error:
error: 'imResampleMex' undefined near line 50 column 5
However all the internal paths within the toolbox should be good. I figured out that the way Matlab and Octave handle mex files is different and tried to build one of the mex files from the C++ function within Octave like this:
mkoctfile --mex imResampleMex.cpp
It fails and throws the following error messages related to the C++ wrappers function:
In file included from imResampleMex.cpp:6:0:
wrappers.hpp:21:24: error: 'wrCalloc' declared as an 'inline' variable
inline void* wrCalloc( size_t num, size_t size ) { return calloc(num,size);
^
wrappers.hpp:21:24: error: 'size_t' was not declared in this scope
wrappers.hpp:21:36: error: 'size_t' was not declared in this scope
inline void* wrCalloc( size_t num, size_t size ) { return calloc(num,size);
^
wrappers.hpp:21:48: error: expression list treated as compound expression in initializer [-fpermissive]
inline void* wrCalloc( size_t num, size_t size ) { return calloc(num,size);
^
wrappers.hpp:21:50: error: expected ',' or ';' before '{' token
inline void* wrCalloc( size_t num, size_t size ) { return calloc(num,size);
^
wrappers.hpp:22:24: error: 'wrMalloc' declared as an 'inline' variable
inline void* wrMalloc( size_t size ) { return malloc(size); }
^
wrappers.hpp:22:24: error: 'size_t' was not declared in this scope
wrappers.hpp:22:38: error: expected ',' or ';' before '{' token
inline void* wrMalloc( size_t size ) { return malloc(size); }
^
wrappers.hpp: In function 'void wrFree(void*)':
wrappers.hpp:23:44: error: 'free' was not declared in this scope
inline void wrFree( void * ptr ) { free(ptr); }
^
wrappers.hpp: At global scope:
wrappers.hpp:28:17: error: 'size_t' was not declared in this scope
void* alMalloc( size_t size, int alignment ) {
^
wrappers.hpp:28:30: error: expected primary-expression before 'int'
void* alMalloc( size_t size, int alignment ) {
^
wrappers.hpp:28:44: error: expression list treated as compound expression in initializer [-fpermissive]
void* alMalloc( size_t size, int alignment ) {
^
wrappers.hpp:28:46: error: expected ',' or ';' before '{' token
void* alMalloc( size_t size, int alignment ) {
^
imResampleMex.cpp: In function 'void resampleCoef(int, int, int&, int*&, int*&, T*&, int*, int)':
imResampleMex.cpp:21:39: error: 'alMalloc' cannot be used as a function
wts = (T*)alMalloc(nMax*sizeof(T),16);
^
imResampleMex.cpp:22:43: error: 'alMalloc' cannot be used as a function
yas = (int*)alMalloc(nMax*sizeof(int),16);
^
imResampleMex.cpp:23:43: error: 'alMalloc' cannot be used as a function
ybs = (int*)alMalloc(nMax*sizeof(int),16);
^
imResampleMex.cpp: In function 'void resample(T*, T*, int, int, int, int, int, T)':
imResampleMex.cpp:48:43: error: 'alMalloc' cannot be used as a function
T *C = (T*) alMalloc((ha+4)*sizeof(T),16); for(y=ha; y<ha+4; y++) C[y]=0;
^
warning: mkoctfile: building exited with failure status
The wrappers.hpp file is looking like this:
#ifndef _WRAPPERS_HPP_
#define _WRAPPERS_HPP_
#ifdef MATLAB_MEX_FILE
// wrapper functions if compiling from Matlab
#include "mex.h"
inline void wrError(const char *errormsg) { mexErrMsgTxt(errormsg); }
inline void* wrCalloc( size_t num, size_t size ) { return mxCalloc(num,size); }
inline void* wrMalloc( size_t size ) { return mxMalloc(size); }
inline void wrFree( void * ptr ) { mxFree(ptr); }
#else
// wrapper functions if compiling from C/C++
inline void wrError(const char *errormsg) { throw errormsg; }
inline void* wrCalloc( size_t num, size_t size ) { return calloc(num,size); }
inline void* wrMalloc( size_t size ) { return malloc(size); }
inline void wrFree( void * ptr ) { free(ptr); }
#endif
// platform independent aligned memory allocation (see also alFree)
void* alMalloc( size_t size, int alignment ) {
const size_t pSize = sizeof(void*), a = alignment-1;
void *raw = wrMalloc(size + a + pSize);
void *aligned = (void*) (((size_t) raw + pSize + a) & ~a);
*(void**) ((size_t) aligned-pSize) = raw;
return aligned;
}
// platform independent alignned memory de-allocation (see also alMalloc)
void alFree(void* aligned) {
void* raw = *(void**)((char*)aligned-sizeof(void*));
wrFree(raw);
}
#endif
I imagine I need to modify this file but my knowledge of C++ and of mex files being close to non-existent, I am struggling figuring a way out of this mountain of errors. I don't even have a clue whether I'm going in the right direction or not... Any help is welcome!
Edit 1:
I modified my wrappers.hpp file adding #include <stdlib.h> to it. A mex file is now created. However, when running the function calling the file, I now get the following error:
error: failed to install .mex file function 'imResampleMex'
error: called from
imResample at line 50 column 4
Here are the steps I used to solve the issue of creating the mex files from the Piotr's Computer Vision Matlab Toolbox for Octave (concerns the cpp files of the folder channels only).
The original mex files that come with the toolbox are built for Matlab and do not work with Octave. While building them from Octave a call is made to the file wrappers.hpp.
This file has to be modified by adding these two lines at the beginning of the file: #include <stdlib.h> and #include "mex.h".
For building the mex file, in the Octave prompt type (while being in the directory of the cpp file):
mkoctfile --mex -DMATLAB_MEX_FILE the_file.cpp
This way the Octave compatible mex file is created.
Edit 23/05/2017 - After receiving more questions from people having trouble generating these files I released the generated files on Github: https://github.com/Eskapp/Piotr_vision_extrafiles_Octave. Feel free to use them.
You'll need to add them manually to the Computer Vision toolbox.

VRPN C++ code compiles on Linux but not Windows

I've built a VRPN client on Linux. It's based on this: http://www.vrgeeks.org/vrpn/tutorial---use-vrpn
Here's some of the code:
vrpn_Analog_Remote * analog = NULL;
vrpn_Button_Remote * button = NULL;
vrpn_Tracker_Remote * tracker = NULL;
// Things happen...
analog = new vrpn_Analog_Remote("pathToAnalog");
analog->register_change_handler(NULL, handleAnalog);
button = new vrpn_Button_Remote("pathToButton");
button->register_change_handler(NULL, handleButton);
tracker = new vrpn_Tracker_Remote("pathToTracker");
tracker->register_change_handler(NULL, handleTracker);
Here are the callbacks refered to in this code:
void handleAnalog(void * userData, const vrpn_ANALOGCB a) {
// Do stuff...
}
void handleButton(void * userData, const vrpn_BUTTONCB b) {
// Do stuff...
}
void handleTracker(void * userData, const vrpn_TRACKERCB t) {
// Do stuff...
}
And here is where all of these references to VRPN are defined:
https://github.com/vrpn/vrpn/blob/master/vrpn_Analog.h#L168
https://github.com/vrpn/vrpn/blob/master/vrpn_Button.h#L225
https://github.com/vrpn/vrpn/blob/master/vrpn_Tracker.h#L284
These compile without even a warning on Linux and can actually be used. Everything worked as expected. All the types here seem to satisfy the compiler, g++.
But on Windows, whether I use Visual Studio 2015 or MinGW's g++, I get this for the first two callback registrations:
invalid conversion from 'void (*)(void*, vrpn_ANALOGCB) {aka void (*)(void*, _vrpn_ANALOGCB)}' to 'vrpn_ANALOGCHANGEHANDLER {aka
void (__attribute__((__stdcall__)) *)(void*, _vrpn_ANALOGCB)}' [-fpermissive]
invalid conversion from 'void (*)(void*, vrpn_BUTTONCB) {aka void (*)(void*, _vrpn_BUTTONCB)}' to 'vrpn_BUTTONCHANGEHANDLER {aka
void (__attribute__((__stdcall__)) *)(void*, _vrpn_BUTTONCB)}' [-fpermissive]
And for the last one, I get a different error:
call of overloaded 'register_change_handler(NULL, void (&)(void*, vrpn_TRACKERCB))' is
ambiguous
Now that I'm typing this, I'm thinking maybe VRPN was compiled differently on Windows and that's why the compiler now has a problem with my code. But I'm very lost as to what to do.
Try declaring your callbacks like this:
void VRPN_CALLBACK handleAnalog(void * userData, const vrpn_ANALOGCB a) {
// Do stuff...
}
For linux, the VRPN_CALLBACK define is empty, so you did not notice any problems there. For windows, the VRPN library devs decided that they expect a callback that adheres to the __stdcall calling-convention. Thus you have to declare your function accordingly, and the most painless+portable way is to use the very same VRPN_CALLBACK define that they provide.
Clues to this came from your links to the code at github:
[vrpn_Analog.h]
typedef void(VRPN_CALLBACK *vrpn_ANALOGCHANGEHANDLER)(void *userdata,
const vrpn_ANALOGCB info);
and the callback define is made here:
[vrpn_Configure.h]
#ifdef _WIN32 // [ ...
#define VRPN_CALLBACK __stdcall
#else // ... ] WIN32 [
#define VRPN_CALLBACK
#endif // ] not WIN32

C++ in Ruby C extensions, pointer problems

I'm tryign to build a Ruby C extension that uses some c++ libraries. Problem is I can't even get a simple "hello world" to work.
//hello_world.cpp
#include <ruby.h>
static VALUE tosCore;
static VALUE my_function( VALUE self )
{
VALUE str = rb_str_new2( "Hello World!" );
return str;
}
extern "C"
void Init_hello_world( void )
{
tosCore = rb_define_module("Core");
rb_define_module_function(tosCore, "my_method", my_function, 0);
}
The output I get is
compiling hello_world.cpp
hello_world.cpp: In function 'void Init_hello_world()':
hello_world.cpp:17:67: error: invalid conversion from 'VALUE (*)(VALUE) {aka lon
g unsigned int (*)(long unsigned int)}' to 'VALUE (*)(...) {aka long unsigned in
t (*)(...)}' [-fpermissive]
In file included from c:/Ruby200/include/ruby-2.0.0/ruby.h:33:0,
from hello_world.cpp:2:
c:/Ruby200/include/ruby-2.0.0/ruby/ruby.h:1291:6: error: initializing argument
3 of 'void rb_define_module_function(VALUE, const char*, VALUE (*)(...), int)'
[-fpermissive]
make: *** [hello_world.o] Error 1
I'm no C/C++ expert. Ruby is my language. I have compiled a few thousand lines of C++ under Rice with no problem, but since I want this particular extension to compile under Windows, Rice is not an option.
It's because the function callback you present to rb_define_module_function is not what the compiler expects. It want a function looking like this:
VALUE my_function(...)
But your function is
VALUE my_function( VALUE self )
Notice the difference in the argument list.
One way to get rid of the error, is to type cast the argument to the type that rb_define_module_function expects:
rb_define_module_function(tosCore, "my_method",
reinterpret_cast<VALUE(*)(...)>(my_function), 0);
You can read about reinterpret_cast here.

Why is Visual C++ changing the name of my method?

I have a problem with the following code:
class MainWindow
{
...
private:
bool CreateWindow(std::string, int, int, int, bool);
...
}
and
bool MainWindow::CreateWindow(std::string title, int width, int height,
int bits, bool fullscreen)
{
...
Visual Studio highlights the method definition with the following error:
int reateWindow(std::string title, int width, int height, int bits, bool fullscreen)
Error: class "MainWindow" has no member called "CreateWindowExW"
and the compiler outputs the following:
warning C4003: not enough actual parameters for macro 'CreateWindowW'
error C2039: 'CreateWindowExW' : is not a member of 'MainWindow'
I noticed that if I change the method name to something else, that does not begin with a capital C, the error goes away. I'm new to Windows development. What gives?
It is simply because CreateWindow is a macro created by Microsoft...
It is defined in WinUser.h.