Dynamic Link Library function export - c++

First the main.h file -
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include <iostream>
#ifndef _BUILD_DLL
#define XXX_API __declspec(dllexport)
#else
#define XXX_API __declspec(dllimport)
#endif
#include "device.h"
// Core functions
namespace xxx
{
XXX_API void createDevice(int w, int h);
}
#endif // __MAIN_H__
main.cpp
#define _BUILD_DLL
namespace xxx
{
XXX_API void createDevice(int w, int h)
{
Device dev;
dev.createDevice(w, h);
}
}
device.h
#ifndef __DEVICE_H__
#define __DEVICE_H__
namespace xxx
{
class Device
{
public:
Device();
virtual ~Device();
XXX_API void createDevice(int width, int height);
}; // end of class
} // end of namespace
#endif
device.cpp
#include "main.h"
namespace xxx
{
Device::Device()
{
}
Device::~Device()
{
}
XXX_API void Device::createDevice(int width, int height)
{
std::cout << "Width: " << width << std::endl;
std::cout << "height: " << height << std::endl;
}
} // end of namespace
This are the files that create the dll and library.
And here is the test.cpp that creates the application which calls that lib functions-
#include "main.h"
int main()
{
xxx::createDevice(800, 600);
std::cout << "Press the ENTER key to exit.";
std::cin.ignore(std::cin.rdbuf()->in_avail() + 1);
return 0;
}
As you can see I am calling createDevice(int, int) to create the device. What I want to know is how do I export the dll calls so that I can get a pointer to that device to call its member function from test.cpp. like this -
#include "main.h"
int main()
{
xxx::Device* dev = createDevice(800, 600);
std::cout << "Press the ENTER key to exit.";
std::cin.ignore(std::cin.rdbuf()->in_avail() + 1);
return 0;
}
Thanks in advance

Change createDevice to this
XXX_API Device* createDevice(int w, int h)
{
Device* dev = new Device();
dev->createDevice(w, h);
return dev;
}
Presumably you should to add a destroyDevice function to free the memory.

Related

glfwGetFrameBufferSize crashes program with access violation

I've been tryna write a renderer using BGFX, and I've set up a method to get the window width, and height - from my window class that wraps GLFWwindow*;
Here is window.h:
#ifndef WINDOW_H
#define WINDOW_H
#include <types.h>
#include <string>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
class RenderWindow {
public:
bool Init(u16 _width, u16 _height, std::string _title);
bool IsCloseRequested() const;
void* GetNativeWindow();
u16 GetHeight();
u16 GetWidth();
void Refresh() const;
GLFWwindow* GlfwWindowPointer = nullptr;
};
#endif
And here is window.cpp
#include "window.h"
#ifdef _WIN32
#define GLFW_EXPOSE_NATIVE_WIN32
#elif __APPLE__
#define GLFW_EXPOSE_NATIVE_COCOA
#endif
#include <GLFW/glfw3native.h>
#include <iostream>
#include <cstdlib>
bool RenderWindow::Init(u16 _width, u16 _height, std::string _title) {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
this->GlfwWindowPointer = glfwCreateWindow(_width, _height, _title.c_str(), nullptr, nullptr);
if(this->GlfwWindowPointer == nullptr) {
std::cout << "[OS] [Window] [FATAL] Window creation failed, exiting" << std::endl;
std::exit(10);
}
return true;
}
bool RenderWindow::IsCloseRequested() const {
return glfwWindowShouldClose(this->GlfwWindowPointer);
}
void RenderWindow::Refresh() const {
glfwPollEvents();
}
u16 RenderWindow::GetHeight() {
int w = 0, h = 0;
glfwGetFramebufferSize(&(*GlfwWindowPointer), &w, &h); // ERROR HAPPENS HERE
return h;
}
u16 RenderWindow::GetWidth() {
int w = 0, h = 0;
glfwGetFramebufferSize(&(*GlfwWindowPointer), &w, &h); // ERROR HAPPENS HERE TOO
return w;
}
void* RenderWindow::GetNativeWindow() {
#ifdef _WIN32
return glfwGetWin32Window(this->GlfwWindowPointer);
#elif __APPLE__
return glfwGetCocoaWindow(this->GlfwWindowPointer);
#endif
}
The thing is, whenever I call these methods - the program crashes in vs debugger with the message:
Exception thrown: read access violation.
window was 0xF242340000.
Of course, the address changes every time - but you get the point. Without calling these two functions, my window works effortlessly. I even got bgfx to clear the screen to purple. Please help me.

glfwCreateWindow() doesnt work out of DLL`s EntryPoint

I have .dll file with my Game Engine and .exe with game.
.exe uses .dll
Both of them use glfw_mt.lib.
In dll There is Window class (Window.cpp,Window.h) where i try to glfwCreateWindow(), but it returns NULL. HOWEVER when i try it in dlls main function (EntryPoint.h) glfwCreateWindow() works fine.
My Window abstractionm fails to create glfw window. I see no reason
EntryPoint.h in dll
#include "Core.h"
#include "Game.h"
#include "Window.h"
#include "glad/glad.h"
#include "GLFW/glfw3.h"
#ifdef NK_PLATFORM_WINDOWS
#define NIKSON_START Nikson::Game* CreateGame(){return
#define NIKSON_END }
extern NIKSON_API Nikson::Game* CreateGame();
static void callback(int error_code, const char* description) {
std::cout << "GLFW ERROR:" << error_code << " " << description << std::endl;
}
int main()
{
LOG("LOADED!");glfwSetErrorCallback(callback);
if (!glfwInit())
{
LOG("GLFW ERROR");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//GLFWwindow* win = glfwCreateWindow(1000, 1000, "Nikson", NULL, NULL);
// LOG(win)
//
///*if (win==nullptr) {
// LOG("FAILED TO CREATE WINDOW")
// return 0;
//}*/
//glfwMakeContextCurrent(win);
Nikson::Window* win = Nikson::CreateWindow("Nikson",1000,1000);
std::cin.get();
//Nikson::Game * game= CreateGame();
////Nikson::Window* win = new Nikson::Window();
//game->Run();
delete win;
}
#endif
Window.h
#pragma once
#include "Core.h"
#include "glad/glad.h"
#include "GLFW/glfw3.h"
namespace Nikson {
struct WindowProp {
std::string Title;
uint32_t Width;
uint32_t Height;
GLFWwindow* WindowPtr;
};
class NIKSON_API Window
{
public:
Window(GLFWwindow* window, const std::string& title = "Nikson",
uint32_t width = 1600,
uint32_t height = 900);
void Tick();
private:
WindowProp m_Properities;
};
NIKSON_API Nikson::Window* CreateWindow(const std::string& title = "Nikson",
uint32_t width = 1600,
uint32_t height = 900);
}
Window.cpp
#include "Window.h"
namespace Nikson
{
Window::Window(GLFWwindow* window, const std::string& title,
uint32_t width,
uint32_t height)
{
m_Properities.Title = title;
m_Properities.Width=width;
m_Properities.Height=height;
m_Properities.WindowPtr = window;
}
void Window::Tick() {
glfwPollEvents();
}
Nikson::Window* CreateWindow(const std::string& title,
uint32_t width,
uint32_t height)
{
GLFWwindow* win = glfwCreateWindow(1000,1000,"Nikson", NULL, NULL);
if (win == NULL) {
LOG(win)
}
/*if (win==nullptr) {
LOG("FAILED TO CREATE WINDOW")
return 0;
}*/
glfwMakeContextCurrent(win);
return new Nikson::Window(win, title, width, height);
}
}

"Cannot open include file: 'vulkan/vulkan.h': No such file or directory" when static library is build as part of a solution in VS 2019

I'm currently experimenting with the vulkan API and have trouble building my solution with VS 2019.
The setup is as follows:
I have a multi-project solution with 2 projects: A static library called *Engine* and an application called *Game*.
External libs: vulkan, GLFW and GLM.
Dependencies are configured almost the same as described in [Vulkan Tutorial][1] with slight adjustments for the static lib, exact setup can be found at the end of this post on screenshots.
My problem is this:
When I build the Engine by itself, everything is fine and no errors occur.
If I build the whole solution and only #include "Engine.h" or "util.h" in "Game.cpp" (source file with main method in Game) then it works as well and if I execute it a window opens and the debug output is correct as well.
But if I #include "Configuration.h" in "Game.cpp" the error as stated in the title occurs.
The only difference I notice between the files is that "Engine.h" and "util.h" do not include any vulkan code but rather their source file counterparts "Engine.cpp" and "util.cpp" do, while "Configuration.h" contains #include "vulkan/vulkan.h".
Does anyone have any idea what might be the problem and how to fix it?
Code
Engine.h
#pragma once
namespace re
{
class REngine
{
public:
void init();
};
}
Engine.cpp
#include "Engine.h"
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
//std
#include <iostream>
namespace re {
void REngine::init()
{
#ifdef _DEBUG
std::cout << "Realms Engine begin initializing." << std::endl;
#endif // _DEBUG
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(800, 600, "Vulkan window", nullptr, nullptr);
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
std::cout << extensionCount << " extensions supported\n";
glm::mat4 matrix;
glm::vec4 vec;
auto test = matrix * vec;
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
}
}
Configuration.h
#pragma once
#include "vulkan/vulkan.h"
namespace re {
class RConfiguration
{
private:
VkApplicationInfo m_appInfo;
const int m_height;
const int m_width;
public:
RConfiguration(
const char* name,
int height, int width,
int major, int minor, int patch
);
const int get_width() { return m_width; }
const int get_height() { return m_height; }
VkApplicationInfo get_app_info() { return m_appInfo; }
};
}
Configuration.cpp
#include "Configuration.h"
namespace re {
RConfiguration::RConfiguration(const char* name, int height, int width, int major, int minor, int patch): m_height(height), m_width(width)
{
m_appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
m_appInfo.pApplicationName = name;
m_appInfo.applicationVersion = VK_MAKE_VERSION(major, minor, patch);
m_appInfo.pEngineName = "Realms Engine";
m_appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
m_appInfo.apiVersion = VK_API_VERSION_1_2;
}
}
Game.cpp
#include <iostream>
#include "Engine.h"
#include "util.h"
#include "Configuration.h"
int main()
{
std::cout << "Hello World!\n";
re::REngine engine;
auto version = re::util::make_version(1, 2, 1);
std::cout << version << std::endl;
engine.init();
}
re::RConfiguration make_config() {
return re::RConfiguration(
"Realms in the Sky",
600,
800,
1, 0, 0
);
}
Project Setup
Engine
Game

'drv' does not name a type

Been looking for awhile and I cant find an answer. All paths are included. I'm referencing a class in another namespace in the class I'm creating.
I'm getting the following error:
src/app/Application.h:30:9: error: 'drv' does not name a type
Code Below. Any help is appreciated!
Main.cpp
int main(int argc, char** argv) {
app::Application program;
program.run();
return 0;
}
LEDs.h
#ifndef LEDS_H
#define LEDS_H
namespace drv {
class LEDs {
public:
LEDs();
void InitLEDs(void);
void SetLEDs(const uint8_t value);
private:
static const uint8_t NUM_LEDs = 5;
};
}
#endif /* LEDS_H */
Application.h
#ifndef APPLICATION_H
#define APPLICATION_H
namespace app {
enum State {
NORMAL = 0,
ZONE,
PAIRING,
STUCK,
BATT,
OFF
};
class Application {
public:
Application();
void run(void);
void execute_loop(void);
private:
bool IDLE;
State STATE;
drv::LEDs Leds; // LINE 30
};
}
#endif // APPLICATION_H
Application.cpp
#include "stdint.h"
#include "stdbool.h"
#include "../drv/LEDs.h"
#include "Application.h"
namespace app {
Application::Application() {
IDLE = false;
STATE = NORMAL;
}
void Application::run(void) {
Leds.InitLEDs();
while(1)
{
if(IDLE) {
PowerSaveIdle();
}
else {
execute_loop();
}
}
}
void Application::execute_loop(void)
{
}
}
LEDs.cpp
#include <stdint.h>
#include "LEDs.h"
namespace drv {
LEDs::LEDs() {
}
void LEDs::InitLEDs() {
SetLEDs(0xff);
}
void LEDs::SetLEDs(const uint8_t value) {
//Removed for readability
}
}
You're missing an #include ... line in Application.h. At the top of that file (or just after the inclusion guards) add the line
#include "LEDs.h"

Inititalze vector of custom class?

I have the following the class:
//Rectangle.h
#include "Point.h"
class Rectangle{
public:
Rectangle();
void setWidth(int);
void setHeight(int);
int getWidth();
int getHeight();
void draw(Point);
private:
int m_width;
int m_height;
};
//Rectangle.cpp
#include <Windows.h>
#include <iostream>
#include <GL/Gl.h>
#include <GL/Glu.h>
#include <GL/Glut.h>
#include "Rectangle.h"
#include "Point.h"
//constructor
Rectangle::Rectangle(){
}
int Rectangle::getHeight(){
return m_height;
}
int Rectangle::getWidth(){
return m_width;
}
void Rectangle::setHeight(int a_height){
m_height = a_height;
}
void Rectangle::setWidth(int a_width){
m_width = a_width;
}
void Rectangle::draw(Point center){
int pointWidth = m_width / 2;
int pointHeight = m_height / 2;
std::cout << "drawing rectangle at" << center.getX() << ", " << center.getY() << std::endl;
glColor3f(1, 1, 0);
glBegin(GL_POLYGON);
glVertex2i( center.getX() - pointWidth, center.getY() - pointHeight );
glVertex2i( center.getX() + pointWidth, center.getY() - pointHeight );
glVertex2i( center.getX() + pointWidth, center.getY() + pointHeight );
glVertex2i( center.getX() - pointWidth, center.getY() + pointHeight );
glEnd();
}
And then I have the following in main.cpp. The problem is with the line vector<Rectangle> rectangles; I get the following error:
std::vector : Rectangle is not a valid template type argument for parameter '_Ty'
#include <Windows.h>
#include <math.h>
#include <string>
#include "Rectangle.h"
#include "Point.h"
#include "Pentagon.h"
#include "Star.h"
#include "StringManip.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <GL/Gl.h>
#include <GL/Glu.h>
#include <GL/Glut.h>
using namespace std;
// Function prototypes for callbacks
void myDisplay(void);
void myInit();
void openFile(string);
Point point;
vector<Point> points;
vector<Rectangle> rectangles;
vector<Pentagon> pentagons;
vector<Star> stars;
I'm at a loss for what's up. I think I've done my class correctly. If anyone could tell me what's wrong, I'd appreciate it.
Here's Point.h and Point.cpp
//Point.h
#ifndef POINT_H
#define POINT_H
class Point {
public:
//default constructor
Point () {
m_xCoord = 0;
m_yCoord = 0;
}
//set x and y
void setX(int a_x);
void setY(int a_y);
//get x and y
int getX();
int getY();
//change x and y by a specified value.
void changeX(int a_x);
void changeY(int a_y);
private:
int m_xCoord;
int m_yCoord;
};
#endif
//Point.cpp
#include "Point.h"
void Point::setX(int a_x){
m_xCoord = a_x;
}
void Point::setY(int a_y){
m_yCoord = a_y;
}
int Point::getX(){
return m_xCoord;
}
int Point::getY(){
return m_yCoord;
}
void Point::changeX(int a_x){
m_xCoord += a_x;
if(m_xCoord < 0){
m_xCoord = 0;
}
}
void Point::changeY(int a_y){
m_yCoord += a_y;
if(m_yCoord < 0){
m_yCoord = 0;
}
}
You're including <Windows.h>, which will pollute the global namespace with many, many declarations, including a function called Rectangle that clashes with your class.
If you actually need the Windows API, your best option is probably to put all your stuff inside a namespace.