简体   繁体   中英

WindowsError: exception: access violation or Windows Error 193 when creating a DLL using ctypes from C++ to Python

I get this error from PyCharm: WindowsError: exception: access violation reading 0x000000504D414C43

It only occurs in Pycharm. When I run the python script from Windows Powershell, it says WindowsError: [Error 193] %1 is not a valid Win32 application . I checked the debugger and a value is being passed but it errors out sometimes gives me null pointers. At first, I thought I was running off the array, but even if I just return 7 (As you see at the bottom) and comment out all of the code it will still do as described.

Questions:

1) Do you have any solutions?

2) Did I set up the DLL properly?

3)Any suggestions?

Thank you so much for your help.

Here is my C++ code:

#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;
}

Here is my python wrapper:

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)

Overall goal:

I have a large file I cannot modify but need to access in C++. There are large lists in the C++ file and I need to iterate through those lists and return a value to a python script.

ctypes only understands C types. You can pass a byte string as const char* and assign it to a std::string if needed. Here's a complete, working example:

C++ code (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 code

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)

Output:

1

Note how the argument types and return value of the DLL function can be specified. That helps catch errors. For example, try passing a Unicode string 'Armaja' instead of the byte string b'Armaja' (Python 3 syntax):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM