Cannot export functions in a DLL - c++

I have a .lib which has a function that I want to make into a DLL.
In the project properties, I have done 2 things,
1. In the C/C++ -> General -> Additional Directories: added the path for the .h file.
2. In the Linker-> General -> Additional Dependies: added the path for the .lib file
Then I made an .h file
#ifndef _DFUWRAPPER_H_
#define _DFUWRAPPER_H_
#include <windows.h>
#include "DFUEngine.h"
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void helloworld(void);
__declspec(dllexport) void InitDLL();
#ifdef __cplusplus
}
#endif
#endif
and made the .cpp file
#include "stdafx.h"
#include "stdio.h"
#include "DFUWrapper.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
void helloworld(void)
{
printf("hello world DFU");
}
DFUEngine* PyDFUEngine()
{
return new DFUEngine();
}
void delDFUEngine(DFUEngine *DFUe)
{
DFUe->~DFUEngine();
}
void PyInitDLL(DFUEngine *DFUe)
{
return DFUe->InitDLL();
}
I made a test with the function helloword. I can see this function in the DLL but not the InitDLL function.
How can I come around this? Please help

Define the following in your DLL header file
#if defined (_MSC_VER)
#if defined (MY_DLL_EXPORTS)
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT __declspec(dllimport)
#endif
#else
#define MY_EXPORT
#endif
Declare your function using that macro
#ifdef __cplusplus
extern "C" {
#endif
MY_EXPORT void helloworld(void);
MY_EXPORT void InitDLL();
#ifdef __cplusplus
}
#endif
And in your .cpp
MY_EXPORT void helloworld(void)
{
printf("hello world DFU");
}
MY_EXPORT void InitDLL()
{
/// blahblah
}
Compile your DLL with MY_DLL_EXPORT defintion....
But be sure that it's not define when you want IMPORT ....

I like exporting functions from DLLs using .DEF files.
This has the added benefit of avoiding name mangling: not only the C++ complex mangling, but also the one happening with __stdcall and extern "C" functions (e.g. _myfunc#12).
You may want to simply add a DEF file for your DLL, e.g.:
LIBRARY MYDLL
EXPORTS
InitDLL #1
helloworld #2
... other functions ...

Related

can i compile .cpp file in to a dll file where the cpp file itself calls the functions from another dll file

So getting in to detail of my question :
I have cpp file which calls functions from a dll file which is written in c.
Here is just an example code
first.cpp:
#include <stdio.h>
#include "Header.h"
#include <windows.h>
typedef double(*MYFUN1)(double);
int main1(int k )
{
MYFUN1 pfun1;
HMODULE hMod;
hMod = LoadLibrary(L"MyMathDll.dll");
pfun1 = (MYFUN1)GetProcAddress(hMod, "PowerOf3");
int ii, max = 20;
for (ii = 0; ii < max; ii++)
{
printf("%le", pfun1(10));
}
return ii;
}
header.h
#pragma once
int main1(int k);
My MyMathDll.dll is formed by following two files:
MyMathDll.c
#include "MyMathDll.h"
double PowerOf3(double UserNumber)
{
return UserNumber * UserNumber * UserNumber;
}
MyMathDll.h
#include <stdio.h>
#if defined (WIN32)
#if defined(FUNCTIONS_STATIC)
#define FUNCTIONS_API
#else
#if defined(FUNCTIONS_EXPORTS)
#define FUNCTIONS_API __declspec(dllexport)
#else
#define FUNCTIONS_API __declspec(dllimport)
#endif
#endif
#else
#define FUNCTIONS_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MYMATHDLL_EXPORTS
#define MYMATHDLL_API __declspec(dllexport)
#else
#define MYMATHDLL_API __declspec(dllimport)
#endif
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
MYMATHDLL_API double PowerOf3(double UserNumber);
#ifdef __cplusplus
}
#endif
Now I am compiling first.cpp to a dll file, so it's basically i am trying make a dll file which already calls the functions from another c dll file.
I built the project a dll file is generated. Now I am making new project with application type .exe and trying load the dll file which is generated from first.cpp
example code of the second cpp which calls the functions from first.cpp
second.cpp
#include <stdio.h>
#include <windows.h>
typedef int (*MYFUN4)(int );
void main()
{
int k = 10;
MYFUN4 pfun4;
HMODULE hMod2;
hMod2 = LoadLibrary(L"first.dll");
pfun4 = (MYFUN4)GetProcAddress(hMod2, "main1");
printf("%d", pfun4(k));
getchar();
}
when i try to run this application, I get a pop window with following message:
Exception triggered at 0x00000000 in ConsoleApplication7.exe: 0xC0000005: Access violation when running at position 0x00000000.
If there is a handler for this exception, the program may still run safely.

'GLEWContext does not name a type' error on ubuntu

I am trying to port a glew_mx project from windows to ubuntu but I always get errors because of GLEWContext being undefined.
error: ‘GLEWContext’ does not name a type
I know that I dont really need GLEWContext on linux but nevertheless I have to define
GLEWContext* glewGetContext();
in order to compile my project. So I created a global GLEWContext and simply return it in glewGetContext.
My window.h code looks like this:
#pragma once
#define GLEW_MX
#define GLEW_STATIC
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#define GLM_SWIZZLE
#include "glm/glm.hpp"
#include "glm/ext.hpp"
#ifdef _WIN32
#define CONTEXT_PREFIX window
#else
#define CONTEXT_PREFIX
#endif
namespace window
{
class Window
{
public:
Window() {}
~Window() {}
//...
#ifdef _WIN32
static void makeContextCurrent(Window* window_handle);
#endif
static Window* createWindow(int win_width, int win_height, const std::string& title, GLFWmonitor* monitor, Window* share);
GLFWwindow* window;
#ifdef _WIN32
GLEWContext* glew_context;
#endif
//...
private:
//...
};
GLEWContext* glewGetContext();
#ifdef _WIN32
//...
#else
GLEWContext* glew_context;
#endif
}
And the code in window.cpp looks like this:
#ifdef _WIN32
GLEWContext* window::glewGetContext()
{
//...
}
#else
GLEWContext* window::glewGetContext()
{
return glew_context;
}
#endif
The error occurs while compiling the last two lines in window.h
Many thanks for your help
It seems the compiler compiles the your Windowclass and gets to the GLEWContext* glew_context line. But GLEWContext may not be defined, so forward declaration might be helpful.
Since you are porting from windows to ubuntu you have to be sure that the #pragma is supported by your compiler. You may change your include guard to
#ifndef WINDOW_H
#define WINDOW_H
// Your code here
#endif

ANSI C code for both Objective-C and C++ code?

In my project there are 3 possible types of files: pure C/Objective-C, pure C++ or Objective-C++ code.
How to divide functions in .h file with #define directives into parts to make this file available for all these files? I don't want to rename all the .m files to .mm because of problems with refactoring.
I know that I can write .h file in C which uses C++ .cpp file using the following code:
#ifndef Chadstone_CCCWrapper_h
#define Chadstone_CCCWrapper_h
#ifdef __cplusplus
#include <string.h>
extern "C"
{
#endif
void minMaxCoordinates(char *c, float *minX, float *minY, float *maxX, float *maxY);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
but what if I want to add functions with using of NSString or list<...>.
You can find it in standard pch-file genarated by Xcode:
#ifdef __OBJC__
#endif
Also you need use CF_EXPORT macro when declaring function to prevent linkage errors.
Example:
#ifndef SOME_H_FILE
#define SOME_H_FILE
#ifdef __OBJC__
#interface SomeObjClass: NSObject
#end
CF_EXPORT void SomeFunctionWithNSString(NSString* str);
#endif
#ifdef __cplusplus
class SomeCPlusPlustClass
{
};
CF_EXPORT void someFunctionWithList(const list<int>& intList);
#ifdef __OBJ__
CF_EXPORT void someComplicatedFunction(NSString* str, const list<int>& intList);
#endif
#endif
CF_EXPORT void someFunction();
typedef struct _SomeStruct
{
} SomeStruct;
#endif

Object Oriented Programming c++ dll Code::Blocks

I'm working on oop c++ with code::Blocks.
These are my first steps in oop because I program in C for microprocessors.
I'm having trouble linking a dll.
My the main from the dll project is:
#include "main.h"
#include "xclass.h"
// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}
This is the header:
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
#include "xclass.h"
/* To use this exported function of dll, include this header
* in your project.
*/
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
void DLL_EXPORT SomeFunction(const LPCSTR sometext);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_H__
Basic stuff as you can see.
The problem is that I am including the class xclass with th main:
#include "xclass.h"
xclass::xclass()
{
//ctor
}
xclass::~xclass()
{
//dtor
}
and header
#ifndef XCLASS_H
#define XCLASS_H
class xclass
{
public:
xclass();
virtual ~xclass();
unsigned int GetCounter() { return m_Counter; }
void SetCounter(unsigned int val) { m_Counter = val; }
protected:
private:
unsigned int m_Counter;
};
#endif // XCLASS_H
I was able to link and use the dll in other project. A can even use the function in the DLL SomeFunction("teste x"); but I can not access and us the class:
#include <iostream>
#include "main.h"
//#include "../cvWrapper/main.h"
using namespace std;
int main()
{
xclass ClassInDll;// not working
SomeFunction("teste x"); //using the function in dll
printf("%d\n", 1);
return 0;
}
The build error is:
||=== testDLL, Debug ===| obj\Debug\main.o||In function main':|
C:\Users\SoftVision\Desktop\PrinterCode\DLL_test\testDLL\main.cpp|9|undefined
reference toxclass::xclass()'|
C:\Users\SoftVision\Desktop\PrinterCode\DLL_test\testDLL\main.cpp|14|undefined
reference to xclass::~xclass()'|
C:\Users\SoftVision\Desktop\PrinterCode\DLL_test\testDLL\main.cpp|14|undefined
reference toxclass::~xclass()'| ||=== Build finished: 3 errors, 0
warnings ===|
Thank for the help...
Actually you should export the class:
class DLL_EXPORT xclass
{
public:
xclass();
virtual ~xclass();
unsigned int GetCounter() { return m_Counter; }
void SetCounter(unsigned int val) { m_Counter = val; }
protected:
private:
unsigned int m_Counter;
};
Be careful when you export a class which is not a pure virtual class because you may meet some problems with a memory alignment. This happens because of different RTL versions in a different compilers. Instead export a pure virtual interface of you class.
class DLL_EXPORT IXClass
{
public:
IXClass();
virtual ~IXClass();
virtual unsigned int GetCounter()=0;
virtual void SetCounter(unsigned int val) =0;
};
Also avoid macros...
Good luck :).
You need to export the class too:
class DLL_EXPORT xclass {
//...
You might need to rearrange your headers a little - e.g. put the #define for DLL_EXPORT somewhere that can be included in both 'main.h' and 'xclass.h'.
http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

GCC (ARM) equivalent to __declspec(dllexport)

When building application for x86, the following code works fine:
#if defined _WIN32
#define LIB_PRE __declspec(dllexport)
#elif defined __unix__
#define LIB_PRE
#else
#define LIB_PRE __declspec(dllexport)
#endif
But gives an error for GCC (ARM). I have found out that __declspec(dllexport) wont work on GCC. If so, what should I use for GCC (ARM)?
Edit:
Its used in many classes. e.g:
class CJsonValueString : public CJsonValue
{
private:
jstring value;
public:
LIB_PRE CJsonValueString(jstring value);
LIB_PRE CJsonValueString(const CJsonValueString * value);
LIB_PRE jstring ToString() const;
LIB_PRE int ToInt() const;
LIB_PRE int64 ToInt64 () const;
LIB_PRE float ToFloat () const;
LIB_PRE void GetValue(jstring & str) const;
};
Basically, you probably don't need anything special. But if you want (and if working on shared objects, i.e. *.so files), learn more about visibility pragmas and visibility function attributes
And the question is more target operating system specific than target machine specific. (I would imagine that an ARM running some obscure Windows8/ARM system would also need your __declspec; conversely, your __declspec has no sense on Linux/x86).
Here's a simplified version of what we use in our code.
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#if defined(__NT__) // MS Windows
#define idaapi __stdcall
#define ida_export idaapi
#if defined(__IDP__) // modules
#define idaman EXTERNC
#else // kernel
#if defined(__X64__) || defined(__NOEXPORT__)
#define idaman EXTERNC
#else
#define idaman EXTERNC __declspec(dllexport)
#endif
#endif
#define ida_local
#elif defined(__UNIX__) // for unix
#define idaapi
#if defined(__MAC__)
#define idaman EXTERNC __attribute__((visibility("default")))
#define ida_local __attribute__((visibility("hidden")))
#else // Linux
#if __GNUC__ >= 4
#define idaman EXTERNC __attribute__ ((visibility("default")))
#define ida_local __attribute__((visibility("hidden")))
#else
#define idaman EXTERNC
#define ida_local
#endif
#endif
#endif
On Linux/OS X, we compile all code by default with -fvisibility=hidden -fvisibility-inlines-hidden and mark up stuff we want to export with idaman, e.g.
idaman bool ida_export set_enum_width(enum_t id, int width);
Since you're exporting C++ methods, you'll probably want to skip the extern "C" part.