WindowsError: исключение: нарушение прав доступа или ошибка Windows 193 при создании DLL с использованием ctypes из C ++ в Python - PullRequest
0 голосов
/ 04 мая 2018

Я получаю эту ошибку от PyCharm: WindowsError: исключение: чтение нарушения доступа 0x000000504D414C43

Это происходит только в Пичарме. Когда я запускаю скрипт python из Windows Powershell, он говорит WindowsError: [Ошибка 193]% 1 не является допустимым приложением Win32 . Я проверил отладчик, и значение передается, но оно выдает ошибки, иногда дает мне нулевые указатели. Сначала мне показалось, что я запускаю массив, но даже если я просто верну 7 (как вы видите внизу) и закомментирую весь код, он все равно будет работать, как описано.

Вопросы:

1) Есть ли у вас какие-либо решения?

2) Правильно ли я настроил DLL?

3) Есть предложения?

Большое спасибо за вашу помощь.

Вот мой код C ++:

#include <iostream>
#include <string>
#include <array>

#include "external_lists.h"

extern creation_object A1[];
extern creation_object  A2[];
extern int A1size;
extern int A2size;


#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int get_creation_data(std::string needed_name){

int A1_size = ( A1size/ sizeof(A1[0])) ;

int A2_size = ( A2size / sizeof(A2[0]))  ;

for (int i = 0; i < A1_size; i++) {
    if (A1[i].name == needed_name) 
    { 
    return A1[i].value->section; 
    }
}
return 7;
}

Вот моя оболочка Python:

import os, sys, re
from ctypes import *

def get_creation_values(value_name):
  trimdll = CDLL('C:\\Documents\\creation.dll')
  return valuedll.get_creation_data(value_name)

if __name__ == "__main__":
  val = get_value('CLAMP')
  print(val)

Общая цель:

У меня есть большой файл, который я не могу изменить, но мне нужен доступ в C ++. В файле C ++ есть большие списки, и мне нужно перебирать эти списки и возвращать значение скрипту Python.

1 Ответ

0 голосов
/ 04 мая 2018

ctypes понимает только типы C. Вы можете передать байтовую строку как const char* и присвоить ее std::string, если необходимо. Вот полный рабочий пример:

C ++ код (test.cpp)

#include <string>

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int get_creation_data(const char* name) {
    std::string needed_name(name);
    if(needed_name == "Armaja")
        return 1;
    return 0;
}

Код Python

from ctypes import *

def get_creation_values(value_name):
  trimdll = CDLL('test')
  trimdll.get_creation_data.argtypes = [c_char_p]
  trimdll.get_creation_data.restype = c_int
  return trimdll.get_creation_data(value_name)

if __name__ == "__main__":
  val = get_creation_values(b'Armaja')
  print(val)

Выход:

1

Обратите внимание, как можно указать типы аргументов и возвращаемое значение функции DLL. Это помогает отлавливать ошибки. Например, попробуйте передать строку Unicode 'Armaja' вместо строки байтов b'Armaja' (синтаксис Python 3):

Traceback (most recent call last):
  File "C:\test.py", line 10, in <module>
    val = get_creation_values('Armaja')
  File "C:\test.py", line 7, in get_creation_values
    return trimdll.get_creation_data(value_name)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...