How to export C++ functions with GCC? - c++

I'm using Code::Blocks to compile a shared library on Ubuntu. When I make a simple main.c file with:
void* CreateInterface()
{
int* x = (int*)malloc( sizeof( int ) );
*x = 1337;
return x;
}
This works fine and I can find the function CreateInterface with dlsym in another application. However, I want the function to create an instance of a class written in C++. I tried the following:
#include "IRender.h"
extern "C"
{
void* CreateInterface()
{
return new Flow::Render::IRender();
}
}
This compiled fine, but now my other application fails to find CreateInterface. How should I deal with this?

I've solved the problem by making a .cpp file with the declaration:
extern "C" void* CreateInterface()
{
return new Flow::Render::IRender();
}
and a .c file with the header like this:
extern void* CreateInterface();

Related

How to make and link when building a C executable from large C++ library

I am a beginner in C and slightly more advanced in C++. This is my first time using make.
I have a large C++ library (written by a third-party that I need to integrate into a C pipeline) and I am hoping to call this library from C. In order to call the C++ library from C, I have 3 files: a .cpp file implementing the calls to the C++ library with C-compatible data types, a .h C-compatible header file linking the C++ implementation functions to C, and a .c file with a main() function that calls the C++ function with C-appropriate data types.
The header file (random_forest.h):
#ifndef RANDOMFOREST_H_
#define RANDOMFOREST_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// opaque forward declared struct
struct random_forest_model;
// pointer to struct used by C code
typedef struct random_forest_model* random_forest_model_t;
random_forest_model_t random_forest_new(const char* model_file_path);
void random_forest_free(random_forest_model_t random_forest_model);
uint8_t *classify(
random_forest_model_t random_forest_model,
const double* independentVariableData,
const double* dependentVariableData,
const size_t numberRows,
const size_t numberColumns,
const char** independentVariableNames
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* RANDOMFOREST_H_ */
In my random_forest.cpp file:
#include <memory.h>
#include "/src/random_forest.h"
#include "/src/rf/src/Forest.h"
#include "/src/rf/src/globals.h"
#include "/src/rf/src/ForestClassificationPrediction.h"
#include "/src/rf/src/utility.h"
using namespace rf; /* comes from Forest.h file */
struct random_forest_model {
std::unique_ptr<rf::Forest> forest;
std::string model_file_path;
}
namespace {
std::unique_ptr<rf::Forest> random_forest_acquire(const char* model_file_path) {
try {
std::unique_ptr<rf::Forest> forest = make_unique<ForestClassificationPrediction>();
forest->InitPredictionModelCpp(model_file_path);
return forest;
} catch(...) {
return nullptr;
}
}
} /* anonymous namespace */
random_forest_model_t random_forest_new(const char* model_file_path) {
try {
auto forest = random_forest_acquire(model_file_path);
return new random_forest_model{std::move(forest), model_file_path};
} catch (...) {
return nullptr;
}
}
void random_forest_free(random_forest_model_t random_forest_model) {
delete random_forest_model;
}
uint8_t* classify(
ranger_random_forest_model_t ranger_random_forest_model,
const double* independentVariableData,
const double* dependentVariableData,
const size_t numberRows,
const size_t numberColumns,
const char** independentVariableNames
) {
try {
/* bunch of stuff here to convert data and run classification */
} catch(...) {
return nullptr;
}
}
Then in my random_forest_implement.c file:
#include "/src/random_forest.h"
int main() {
const char model_file_path[] = "path/to/model";
random_forest_model_t random_forest = random_forest_new(model_file_path);
/*
some code here to ingest a data file - outputting the data for random_forest_classify
yielding: X, y, numberRows, numberColumns, varNames
*/
uint8_t *classes = classify(
random_forest, X, y, numberRows, numberColumns, varNames
);
random_forest_free(random_forest);
free(X);
free(y);
free(varNames);
free(classes);
return EXIT_SUCCESS;
}
This is a very long-winded way to ask how to compile this program into a single executable. I've tried to compile with the following make file:
CC ?= gcc
CP ?= g++
random_forest_implement: random_forest_implement.o random_forest.o
$(CP) -o random_forest_implement random_forest_implement.o random_forest.o
random_forest.o: random_forest.cpp random_forest.h
$(CP) -c random_forest.cpp
random_forest_implement.o: random_forest_implement.c random_forest.h
$(CC) -c random_forest_implement.c random_forest.h
clean:
$(RM) *.o random_forest
When I try to make this (make -f random_forest_make.mk), I get three lines that appear (?) successful, and I receive a lot of errors about undefined reference, e.g.:
cc -c random_forest.c random_forest.h
g++ -c random_forest.cpp
g++ -o random_forest_implement random_forest_implement.o random_forest.o
/usr/bin/ld: random_forest.o: in function `(anonymous namespace)::random_forest_acquire(char const*)':
random_forest.cpp:(.text+0x44f): undefined reference to `rf::Forest::InitPredictionModelCpp(<bunch of args necessary to method>)
I'm not entirely sure where to go from here, but I suspect I'm not compiling everything correctly. As you can see, I have several files on which my random_forest.cpp file depends. Do I need to compile each of these? And their dependencies? Is there a best/efficient method for doing this, or do I need to write a make file that generates an object file for every .cpp file in the /src/rf/src/ directory?
You cannot build a C executable including C++ sources. You can only create C++ executables if you include any C++ code. C++ supports C source modules to be linked against for compatibility reasons but C compilers were not designed to link C++ modules (there’s no backwards compatibility between C and C++, C was created before)
For this reason, you can only use c++ compiler to link C++ mixed with C sources (even if main is defined in a C source file) because this action will make C++ compiler to call the linker in C++ mode and link both C/C++ modules and call the C++ standard library modules and run time. Despite of the similarities between both languages, the memory layout of a C++ executable is more complex than the layout of a simple C-only program

Initialisation of C++ structures from C

I'm trying to use opencv C++ library with another lib in C. So I've defined a structure in an .hpp file which I've added to the .h of the C library
typedef struct {
cv::FileStorage fs;
cv::Mat mat;
} myCPPStruct;
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
myCPPStruct * mycppstruct;
} myCStruct;
void initialize_myCPPStruct(myCPPStruct * mycppstruct);
#ifdef __cplusplus
}
#endif
In the .c files the initializer for myCStruct calls initialize_myCPPStruct which is defined in a .cpp file somewhat as:
void initialize_myCPPStruct(myCPPStruct * mycppstruct){
mycppstruct = {};
mycppstruct->fs = cv::FileStorage( "file.txt", cv::FileStorage::READ );
mycppstruct->mat = cv::Mat(3,3,CV_8UC3);
}
But once it tries to allocate a value to mycppstruct->fs, it gets a segmentation fault. I assume this is because there is no memory allocation in C, but I've tried
std::memset(stitcher->fs,0,sizeof(cv::FileStorage));
which also doesn't work as it can't parse cv:FileStorage as void *.
Will I have to use the deprecated C OpenCV library to make this work?
EDIT - More details about the compilation.
For the C lib, I recompile (without linking ie with the -c option)all the .c files where I've added C++ functions or structures using g++ while making sure I add the __cplusplus guards in the .h files. All the .c files without C++ code already have .o files compiled with gcc. I then compile the whole program with g++ while making sure to include the relevant library files. There are no compiler errors.
It seems the structure itself has not been created.
You might try this (or something similar):
myCPPStruct* initialize_myCPPStruct()
{
myCPPStruct* result;
result = new myCPPStruct();
result->fs = cv::FileStorage( "file.txt", cv::FileStorage::READ );
result->mat = cv::Mat(3,3,CV_8UC3);
return (result);
}
You need to allocate the memory for your structure:
myCPPStruct = malloc(sizeof(myCPPStruct));
Use the above line instead of:
mycppstruct = {};
Also,since your function is passing in the pointer and allocating the memory internally you need to pass a pointer to the pointer or the allocation will not be passed back:
void initialize_myCPPStruct(myCPPStruct** mycppstruct){
if ( mycppstruct == NULL ) {
//Abort as no address of the pointer to allocate passed
return;
}
*myCPPStruct = malloc(sizeof(myCPPStruct));
(*mycppstruct)->fs = cv::FileStorage( "file.txt", cv::FileStorage::READ );
(*mycppstruct)->mat = cv::Mat(3,3,CV_8UC3);
}
Or you could just change the above to:
myCPPStruct* initialize_myCPPStruct(void) {
myCPPStruct* ptr = malloc(sizeof(myCPPStruct));
ptr->fs = cv::FileStorage( "file.txt", cv::FileStorage::READ );
ptr->mat = cv::Mat(3,3,CV_8UC3);
return ptr;
}
First, let me point out the sentence which confuse me.
there is no memory allocation in C
Yes, there is. Have a look to malloc function.
char *my_allocated_string = malloc(sizeof(char) * 42);
Here you are, you've allocated an array of character of size 42.
Now, have a look to : mycppstruct = {};
That's not how you allocate a structure in C. You have to call... malloc() !
my_struct *s = malloc(sizeof(my_struct));
s->fs = 42;
Ok. Done. Feels better.
Well, first of all, you have to create a wrapper around your C++ code. Why ? Because C++ allows multiple definition of a given function (also call symbol) :
int my_func(int);
int my_func(char);
This is valid in C++. But, think about it, how is the compiler able to let two functions with the same name exist ? Well it's not. It uses a technique named mangling when evaluating the functions to create 2 different names. Mangling is use on everything function and method. Event on single functions.
C is not able (and willing) to create several functions with the same name. Otherwise, you will experience a kind of function-already-implemented error. When you declare :
int my_func(int);
the C compiler will create the symbol : my_func. No mangling.
To make both language interact, you need to reference to a symbol understandable by the C compiler. If you call my_func from a C source file, the C compiler will look for my_func symbol. Bu since C++ will modify its my_func symbol into something like _ZN9myfuncE, the linkage will fail. That's why you have to says to the C++ compiler to not use mangling on the function you expose to C. That's why you need extern "C" { }.
Feeww, so far so good...
Now you have to embed you C API into an extern "C" block :
In my_c_api.h :
void my_func(int);
void my_func(char);
In my_c_api.cpp :
#include "my_c_api.h"
extern "C" void my_func_i(int i) { my_func(i); }
extern "C" void my_func_c(char c) { my_func(c); }
You compile it to create your C++ library.
In your C compilation pipeline, you link against your new C++ library and header files. Then :
#include "<path_to_my_c_api.h>"
void c(int i,char s)
{
my_func_i(i);
my_func_c(c);
}
You cannot compile C++ code with C compiler. You have to compile te C++ code independently.
More on ISO CPP.

How do you load a custom module into Lua?

This has been driving me nuts for a long time now. I have followed every tutorial I could find on the internet (here are couple examples[ [1], [2] of the maybe half dozen good ones found via Google search), and still no clear explanation. Although it seems it must be something fairly simple as that lack of a documented explanation implies that it's something most people would take for granted.
How do I load a custom module into Lua?
On the advice of questions like this one, I have written a module that builds a shared library with the expectation that I would be able to load it through a require call. However, when I do that I get undefined symbol errors, despite those exact symbols appearing in the list from the command nm -g mylib.so.
Those two tutorials I linked before aim to create executables that look wrappers of the *.lua file. That is, the built *.exe file should be called to run the Lua program with the custom module.
I understand that these types questions are asked here fairly frequently (as noted in this answer), but I am still at a loss. I tried some of the binding packages (Luabind and OOLua), but those didn't work out great (e.g. my earlier question--which I did ultimately figure out, sort of).
I have implemented a class in C++
I have wrapped the constructors, destructors, and functions with thunks
I have built it errorless-ly as a shared library
Yet no matter what I get undefined symbol: ... errors when I try to load it as mod = require('mylib.so'). How do I do this?
Working Example of a Library of Functions
For the record, just registering a basic function works fine. The below code, when built as libluatest.so, can be run in Lua using the commands:
> require('libluatest')
> greet()
hello world!
libluatest.cpp
extern "C"
{
#include <lualib.h>
#include <lauxlib.h>
#include <lua.h>
}
#include <iostream>
static int greet(lua_State *L)
{
std::cout << "hello world!" << std::endl;
return 0;
}
static const luaL_reg funcs[] =
{
{ "greet", greet},
{ NULL, NULL }
};
extern "C" int luaopen_libluatest(lua_State* L)
{
luaL_register(L, "libluatest", funcs);
return 0;
}
Failing Example of a Class
This is what I am stuck on currently. It doesn't seem to want to work.
myObj.h
#include <string>
class MyObj
{
private:
std::string name_;
public:
MyObj();
~MyObj();
void rename(std::string name);
};
myObj.cpp
extern "C"
{
#include <lualib.h>
#include <lauxlib.h>
#include <lua.h>
}
#include <iostream>
#include "myObj.h"
void MyObj::rename(std::string name)
{
name_ = name;
std::cout << "New name: " << name_ << std::endl;
}
extern "C"
{
// Lua "constructor"
static int lmyobj_new(lua_State* L)
{
MyObj ** udata = (MyObj **)lua_newuserdata(L, sizeof(MyObj));
*udata = new MyObj();
luaL_getmetatable(L, "MyObj");
lua_setmetatable(L, -1);
return 1;
}
// Function to check the type of an argument
MyObj * lcheck_myobj(lua_State* L, int n)
{
return *(MyObj**)luaL_checkudata(L, n, "MyObj");
}
// Lua "destructor": Free instance for garbage collection
static int lmyobj_delete(lua_State* L)
{
MyObj * obj = lcheck_myobj(L, 1);
delete obj;
return 0;
}
static int lrename(lua_State* L)
{
MyObj * obj = lcheck_myobj(L, 1);
std::string new_name = luaL_checkstring(L, 2);
obj->rename(new_name);
return 0;
}
int luaopen_libmyObj(lua_State* L)
{
luaL_Reg funcs[] =
{
{ "new", lmyobj_new }, // Constructor
{ "__gc", lmyobj_delete }, // Destructor
{ "rename", lrename }, // Setter function
{ NULL, NULL } // Terminating flag
};
luaL_register(L, "MyObj", funcs);
return 0;
}
}
Compiled into libmyObj.so using a simple CMake build with C++11 standard flags on.
Error
> require('libmyObj')
error loading module 'libmyObj' from file './libmyObj.so':
./libmyObj.so: undefined symbol: _ZN5MyObjC1Ev stack traceback: [C]:
? [C]: in function 'require' stdin:1: in main chunk [C]: ?
I am dealing with Lua 5.1 on Ubuntu 14.04.
I am wondering if it has something to do with the mix of C and C++...
It seems that you do not implement:
MyObj() ; ~MyObj();
and be careful with luaopen_* function, since module name is myObj, function name should be luaopen_libmyObj.

Using a C++ library for a C application

I have a command line (+HTTP interface) audio application in C, which currently is being compiled with gcc on Mac OSX, but which I would like to keep this application linux compatible.
However, I would like to use the freeverb3 library. This is in C++. I would prefer not to convert all my code to C++. I don't (as far as I can see) need to call any C code from C++, nor will I need to use C++ objects in my C code. Simple method calls passing arrays of doubles plus a few ints as arguments will be all that I need in terms of interaction from my main application an the C++ code.
From some quick googling, it seems that I can write a C++ interface module, which can then expose some c compatible functions that I can call to make use of freeverb3. I"ve written a micro example to see how this might work. For this example, I have a dummy c++ file called test.cpp:
#include <iostream>
using namespace std;
class test_class
{
int a;
public:
int get_a();
void set_a( int v );
};
int test_class::get_a()
{
return a;
}
void test_class::set_a( int v )
{
a = v;
}
static test_class *c;
extern "C"
{
void init();
void set( int v );
int get();
}
void init()
{
c = new test_class();
}
void set( int v )
{
c->set_a( v );
}
int get()
{
return c->get_a();
}
I have a dummy c file that calls the functions:
#include <stdio.h>
/* Forward declaratoins for extern "C" functions in C++ code */
void init();
int get();
void set( int v );
/* C language code that references functions in C++ code */
int main()
{
init();
set( 55 );
printf( "value: %d\n", get() );
set( get() + 12 );
printf( "value: %d\n", get() );
return 0;
}
And, I have a makefile that creates an executable.
test: test.o user.o
g++ -o test user.o test.o
test.o: test.cpp
g++ -c test.cpp
user.o: user.c
gcc -c user.c
Is this a good way of using C++ code from C? Is there a better/more sophisticated/more traditional way of achieving this aim?
You might want to think about it the other way.
Write your higher level application in C++, invoke the C++ library where you want without complications and call all your current C modules from the C++ level.
IMHO, this is easier to achieve than doing the same with C as high level.
If you intend to use more than one C++ object from C you need to pass an extra instance pointer (this) to the C wrapper functions:
struct A {
A();
~A();
void set(int);
};
The C wrapper:
extern "C"
{
struct A* a_create(void);
void a_destroy(struct A*);
void a_set(struct A*, int);
}
You may also like to catch all C++ exceptions in the C wrapper functions and convert them to error codes.
Pass a pointer to your object instead of using a static variable.
C++ class:
class Foo
{
public:
void doStuff();
};
Common include file:
#ifdef __cplusplus
extern "C"
{
#endif
void Foo_doStuff(void* handle);
void* Foo_create();
void Foo_destroy(void* handle);
#ifdef __cplusplus
}
#endif
Wrapper functions
void Foo_doStuff(void* handle)
{((Foo*)handle)->doStuff();}
void* Foo_create()
{return new(nothrow)Foo;}
void Foo_destroy(void* handle)
{delete (Foo*)handle;}
Not sure whether this goes from C to C++ but it is well worth looking into Swig
Make an extern "C" wrapper in C++, e.g.
// myWrapper.h
#ifdef __cplusplus
extern "C"
{
#endif
void func1(void);
int func2(void);
void func3(char const *str_ptr, size_t len);
#ifdef __cplusplus
}
#endif
// myWrapper.cpp
#include "myWrapper.h"
#include "your_cpp_library.h"
void func3(char const *str_ptr, size_t len)
{
std::string s(str_ptr, str_ptr + len);
call_cpp_function(s);
}
// etc.
In your C code you #include "myWrapper.h" and call those functions. Make sure that:
The code in myWrapper.h stays in the common subset of C and C++
You do not do any cross-boundary resource allocation
The latter might work but it's best to avoid it to be safe. The latter point means that if memory is to be allocated, it must be allocated and freed by the same side; e.g. you can't have the C++ side call malloc and give a pointer to the C side, and then have the C side call free. You have to pass the pointer back to whoever allocated it and let them free it.
Important: as Alf says in a comment, you must have main() in C++ and use the C++ linker , when doing C - C++ inter-linking. This is not a big hurdle though; you can rename your C code's main() function to main2(), and have the C++ code do extern "C" int main2(); and call it.

Including C-DLL from C++

This feels like a noob question, so if it's a dupe, please point me to the right location :)
I tried including a DLL written in C into a C++ program. It didn't work; gcc said
test.cpp: xxx: error: too many arguments to function.
Here's a minimal working example:
Wrapper for DLL functions:
/* myWrapper.h */
#ifndef _MYWRAPPER_H
#define _MYWRAPPER_H
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
extern FARPROC EXPORTED_functionNameP;
int GetDLLpointers();
#ifdef __cplusplus
}
#endif
#endif
Implementation thereof:
/* myWrapper.c */
#include <windows.h>
#include "myHeader.h"
#ifdef __cplusplus
extern "C" {
#endif
HINSTANCE drvsHANDLE;
extern FARPROC EXPORTED_functionNameP;
int GetDLLpointers()
{
static int result;
drvsHANDLE = LoadLibrary("myLibrary.dll");
if (drvsHANDLE == NULL) return (result=0);
EXPORTED_functionNameP = GetProcAddress(
drvsHANDLE, "originalFunctionName");
if (EXPORTED_functionNameP == NULL) return (result = 0);
return (result = 1);
}
#ifdef __cplusplus
}
#endif
Naturally, I haven't written these nor the library myself, and preferably, they should all stay untouched. I did however add the extern "C" lines.
Then, my main file:
// my Main
#include <windows.h>
#include "myHeader.h"
int main(int argc, char **argv)
{
int arg = 1;
EXPORTED_functionNameP(arg);
return 0;
}
Build commands:
gcc -I. -c -o myHeader.o myHeader.c -L. -lmyLibrary
g++ -I. -o main.exe myMain.cpp myHeader.o -L. -lmyLibrary
It works fine if I rewrite my main.cpp into valid C and compile with gcc instead of g++.
I tried changing extern "C" into extern "C++" to no avail, I tried all permutations or gcc and g++ for the two build commands, nothing.
I know it's something to do with name mangling, but I thought gcc would take care of that when you include the extern "C" lines...Can someone please explain what I'm missing here?
In case it matters --
Windows XP Pro (will be Win7 later on)
(MinGW) gcc 4.6.2
I know this is a very old question, but I am having exactly the same issues but in relation to writing a generic wrapper template for wrapping calls to LoadLibrary() and GetProcAddress()
Taking https://blog.benoitblanchon.fr/getprocaddress-like-a-boss/ as inspiration, it looks like he is taking FARPROC as a kind of "void* for Windows functions" and then casting it to the correct type subsequently.
I needed to tweak that code a little to work for me, and reproduce it here:
class ProcPtr
{
public:
explicit ProcPtr(FARPROC ptr) : m_ptr(ptr) {}
template <typename T>
operator T* () const { return reinterpret_cast<T*>(m_ptr); }
private:
FARPROC m_ptr;
};
class DllHelper
{
public:
explicit DllHelper(LPCTSTR filename) : m_module(LoadLibrary(filename)) {}
~DllHelper() { FreeLibrary(m_module); }
ProcPtr operator[](LPCSTR proc_name) const
{
return ProcPtr(::GetProcAddress(m_module, proc_name));
}
private:
HMODULE m_module;
};
So, with that helper code now available we can use it to write a wrapper class that encapsulates several functions in the Advapi32 library:
class Advapi32
{
public:
Advapi32() : m_dll(TEXT("Advapi32"))
{
getUserName = m_dll["GetUserNameA"];
openSCManager = m_dll["OpenSCManagerA"];
bogusFunction = m_dll["BogusFunctionThatDoesNotExist"];
}
decltype(GetUserNameA)* getUserName;
decltype(OpenSCManagerA)* openSCManager;
decltype(GetWindowsDirectoryA)* bogusFunction;
private:
DllHelper m_dll;
};
bogusFunction is a function with the same signature as GetWindowsDirectoryA but which doesn't exist in Advapi32. This is what I was trying to achieve - graceful fallback on an older OS which might not have a certain function.
So, finally a test app...
int main()
{
Advapi32 advapi32;
auto func1 = advapi32.getUserName;
if (func1)
{
TCHAR infoBuf[256];
DWORD bufCharCount = sizeof(infoBuf);
if (func1(infoBuf, &bufCharCount))
{
std::cout << "Username: " << infoBuf << std::endl;
}
}
auto func2 = advapi32.openSCManager;
if (func2)
{
SC_HANDLE handle = func2(NULL, NULL, SC_MANAGER_CONNECT);
if (handle)
{
std::cout << "opened SC Manager" << std::endl;
}
}
auto func3 = advapi32.bogusFunction;
if (func3)
{
std::cerr << "This should not happen!" << std::endl;
}
else
{
std::cout << "Function not supported" << std::endl;
}
}
Output:
Username: TestAccount
opened SC Manager
Function not supported
Note: This was compiled as a Windows 32-bit console application with MBCS rather than Unicode, under VS2019 with the VS2015_XP toolset, since that is what I am needing to target (don't ask).
The FARPROC type is a function pointer for a function that takes no parameters. You should declare EXPORTED_functionNameP like so (replacing void with whatever the function really returns):
extern void (*EXPORTED_functionNameP)(int);
And initialize it like so (the returned value from GetProcAddress() pretty much always needs to be cast to the correct type):
EXPORTED_functionNameP = (void (*)(int)) GetProcAddress(drvsHANDLE, "originalFunctionName");
A typedef for the funciton type might make things a bit more readable.
There is a difference between C and C++.
int (FAR WINAPI * FARPROC) ()
In C, the FARPROC declaration indicates a callback function that has an unspecified parameter list. In C++, however, the empty parameter list in the declaration indicates that a function has no parameters.
The MSDN page on CallWindowProc explains a bit more.
After a quick Google search, it seems that FARPROC is defined as this:
typedef int (FAR WINAPI *FARPROC)();
That is, FARPROC is a function that returns an int and takes no arguments. So you can't use it for any other case.
Instead declare EXPORTED_functionNameP like this:
extern void (*EXPORTED_functionNameP)(int);
Now EXPORTED_functionNameP is a pointer to a function that takes an int argument and returns no value.
It is because of FARPROC is defined as:
int (FAR WINAPI * FARPROC) ()
So you can not pass any parameters to such function in C++. For fix it you should define EXPORTED_functionNameP as pointer to function with equal semantics as defined in DLL-library. For example:
typedef (void* EXPORTED_functionNameP)(int value);
EXPORTED_functionNameP ExportedFns;
...
ExportedFns = GetProcAddress(drvsHANDLE, "originalFunctionName");
FARPROC is defined as
typedef int (FAR WINAPI *FARPROC)();
When you pass an additional argument although the argument list of the prototype is empty you get the error.
You need a proper prototype definition for PORTED_functionNameP and cas the result from GetProcAddress to that type in your GetDLLPopinters functions.