@YakovSava
Питонячий сишник

OSError: exception: access violation reading, ctypes, Python, что делаю не так?

DLL файл скомпилированный при помощи g++ (ноут Visual Studio не тянет) не записывает данные в файл, однако он его открывает, причём успешно.

writer.cxx (writer.dll)
# include <fstream>
using namespace std;


extern "C" {
int write(char* filename, char* all_lines) {
	ofstream file;
	file.open(filename);
	if (file.is_open()) {
		file << all_lines << endl;
		file.close();
		return 1;
	} else {
		file.close();
		return 0;
	}
}
}


downoloader.py
from ctypes import *
from os import getcwd
from sys import platform

if platform in ['linux', 'linux2']:
	end = '.so'
elif platform in ['win32', 'cygwin', 'msys']:
	end = '.dll'

writer = CDLL(f'./writer{end}')

a = c_char_p(f'{getcwd()}\\file.txt'.encode())
b = c_char_p(b'Help me pls')

writer.write.argtypes = [c_char_p, c_char_p]
writer.write.restype = c_int

print(writer.write(a, b))


Команды которые я использую для компиляции
g++ -c -fextended-identifiers -std=c++20 -fPIC writer.cxx -o writer.o
g++ -shared -fextended-identifiers -std=c++20 -Wl,-soname,writer.dll -o writer.dll  writer.o
  • Вопрос задан
  • 561 просмотр
Решения вопроса 1
@YakovSava Автор вопроса
Питонячий сишник
В Общем я нашёл решение. Используйте getcwd() из os для того что бы указать полный путь (И НЕ ИСПОЛЬЗУЙТЕ "/" В windows!)

test.py
from os import getcwd
from ctypes import *

dll = cdll.LoadLibrary("./writer.dll")

dll.write.argtypes = [c_char_p, c_char_p]
dll.write(f"{getcwd()}\\filename.txt".encode(), b"Hello world!")


writer.cxx
# include <fstream>
using namespace std;

extern "C" __declspec(dllexport) void write(char* filename, char* lines) {
    ofstream file;
    file.open(filename, ios_base::out);
    if (file.is_open()) {
        file << lines << endl;
        file.close()
    }
}


compiling (clang)
clang++ -c -o writer.o writer.cxx
clang++ -shared -v -o writer.dll writer.o


Дело было не связано с питоном, как предпологали некоторые
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
a = c_char_p(f'{getcwd()}\\file.txt'.encode())
b = c_char_p(b'Help me pls')

Тут есть проблема. Ты получаешь указатель на объект, но ты не хранишь ссылку на этот объект.
Что, если Питон сразу же его подберёт сборщиком мусора? У тебя указатель будет указывать на адрес, где был объект, а что там сейчас - фз. Если память не будет освобождена, то обращение может быть удачным. Если страницу памяти освободят - то поймаешь access violation.
Положи строку в переменнную, и бери указатель по переменной. Тогда объект будет жить, пока жива переменная.
Во-всяком случае, я бы начал с этого.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы