Я пытаюсь создать простой движок, написанный на C ++ и обернутый в python с типами. Я хочу установить функцию рисования окна с помощью ctypes CFUNCTYPE. К сожалению, по каким-то причинам не работает. Понятия не имею, где может быть ошибка, поэтому публикую все. Я получаю сообщение об ошибке
exception: access violation reading 0x000001D15D9D0B51
File "C:\Pancake2d\Pancake2d-python\pancake2d\window.py", line 28, in run
pancake2d.API.lib.runWindow(self.obj)
File "C:\Pancake2d\Pancake2d-python\test.py", line 13, in <module>
wnd.run()
, но адрес, к которому пытается получить доступ код, каждый раз отличается, поэтому я предполагаю, что эта функция просто не установлена, и я пытаюсь вызвать неопределенное значение.
pancake2d. cpp
#include<new>
#define GLEW_BUILD
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "pancake2d.h"
#include "classes/window.h"
const char * version()
{
const char* result = "Pancake2d - version 0.0.1";
return result;
}
bool init() {
if (!glfwInit()) {
return false;
}
//glewInit();
return true;
}
window* createWindow(int width, int height, const char* title) {
return new window(width, height, title);
}
void deleteWindow(void* ptr) {
delete ptr;
}
void closeWindow(window* wnd) {
wnd->close();
}
void runWindow(window* wnd) {
wnd->run();
}
bool setDrawingFunction(window* wnd, void(*ptr)()) {
try {
wnd->setDrawFunction(ptr);
}
catch(...) {
return false;
}
return true;
}
void setUpdateFunction(window* wnd, void(*ptr)()) {
wnd->setUpdateFunction(ptr);
}
pancake2d.h
#pragma once
#include <new>
#include "classes/window.h"
#include "graphics.h"
#ifdef PANCAKE2D_EXPORTS
#define exp __declspec(dllexport)
#else
#define imp __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
exp const char* version();
exp bool init();
exp window* createWindow(int, int, const char *);
exp void deleteWindow(void*);
exp void closeWindow(window*);
exp void runWindow(window*);
exp bool setDrawingFunction(window*, void(*ptr)());
exp void setUpdateFunction(window*, void(*ptr)());
#ifdef __cplusplus
}
#endif
window.h
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class window
{
public:
GLFWwindow* wnd;
window(int width, int height, const char* title);
void close();
void (*update)();
void (*draw)();
void run();
void setDrawFunction(void (*fnptr)());
void setUpdateFunction(void (*fnptr)());
};
окно. cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "window.h"
void default_draw() {
glClear(GL_COLOR_BUFFER_BIT);
}
void default_update() {
}
window::window(int width, int height, const char* title)
{
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_COMPAT_PROFILE, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
wnd = glfwCreateWindow(width, height, title, NULL, NULL);
if (wnd == NULL) { glfwTerminate(); return; }
glfwMakeContextCurrent(wnd);
if (glewInit() != GLEW_OK) {
glfwTerminate();
return;
}
//void (*draw)(window*) {default_draw};
draw = default_draw;
update = default_update;
}
void window::close() {
glfwDestroyWindow(wnd);
}
void window::setDrawFunction(void(*fnptr)()) {
draw = fnptr;
}
void window::setUpdateFunction(void(*fnptr)()) {
update = fnptr;
}
void window::run() {
while (glfwWindowShouldClose(wnd) == 0)
{
glClear(GL_COLOR_BUFFER_BIT);
//update(this);
draw();
glfwSwapBuffers(wnd);
glfwPollEvents();
}
close();
}
pancake2d / window.py
from ctypes import *
import pancake2d.API
function_empty = CFUNCTYPE(None)
def init():
pancake2d.API.lib.createWindow.argtypes = [c_int, c_int, c_char_p]
pancake2d.API.lib.createWindow.restype = c_void_p
pancake2d.API.lib.deleteWindow.argtypes = [c_void_p]
pancake2d.API.lib.closeWindow.argtypes = [c_void_p]
pancake2d.API.lib.runWindow.argtypes = [c_void_p]
pancake2d.API.lib.setDrawingFunction.argtypes = [c_void_p, function_empty]
pancake2d.API.lib.setDrawingFunction.restype = c_bool
class Window:
def __init__(self, width: int = 500, height: int = 500, caption: str = "Pancake2d Project"):
self.obj = pancake2d.API.lib.createWindow(width, height, c_char_p(bytes(caption, encoding="UTF-8")))
def close(self):
pancake2d.API.lib.closeWindow(self.obj)
def run(self):
pancake2d.API.lib.runWindow(self.obj)
def set_draw(self, fun):
return pancake2d.API.lib.setDrawingFunction(self.obj, function_empty(fun))
pancake2d / init .py
from ctypes import *
import os
import pancake2d.API
import pancake2d.useless
import pancake2d.window
import pancake2d.graphics
mypath = os.path.dirname(os.path.realpath(__file__))
def init():
print(os.path.join(mypath, "Pancake2d.dll"))
os.environ['PATH'] = os.path.join(mypath, "lib") + os.pathsep + os.environ['PATH']
pancake2d.API.lib = cdll.LoadLibrary(os.path.join(mypath, "Pancake2d.dll"))
pancake2d.API.lib.init()
pancake2d.useless.init()
pancake2d.window.init()
pancake2d.graphics.init()
test.py
import pancake2d, time, random
from ctypes import *
pancake2d.init()
def draw():
pancake2d.graphics.setBackgroundColor(random.randint(1, 255), random.randint(1, 255), random.randint(1, 255))
wnd = pancake2d.window.Window(700, 200, "Test")
if not wnd.set_draw(draw):
print ("Something went wrong") # This does not happen
pancake2d.graphics.setBackgroundColor(128, 128, 128)
wnd.run()
Буду очень благодарен за любой ответ.