Ctypes, Python3.5, Oserror: Exception: Access Violation Writing 0X00000000
Researching Other Similar Errors, I Think That I Have an Issue with a an Illegal Operation Such as Writing to an Address That I Shouldn't Be. I'm Not Sure How...
Researching other similar errors, I think that I have an issue with a an illegal operation such as writing to an address that I shouldn't be. I'm not sure how to resolve this. Any help please?
Exact error I'm getting:
in GetSoftwareVersion()
result = f(LCP_Version, FCP_Version)
OSError: exception: access violation writing 0x00000000
Functions I'm calling
x = GetSoftWareVersion()
print(x)
GetSoftwareVersion() contents
def GetSoftwareVersion():
f = shim.GetSoftwareVersion
LCP_Version = ct.c_char_p(0)
FCP_Version = ct.c_char_p(0)
result = f(LCP_Version, FCP_Version)
if result:
print(find_shim_error(result))
return LCP_Version.contents.value, FCP_Version.contents.value
edit: adding the relevant C++ code
PCSHIMDLL_API error_status_type GetSoftwareVersion(
char* LCP_Version,
char* FCP_Version
)
{
error_status_type return_status = SUCCESS;
string LCP_V("");
string FCP_V("");
LaserIDType_var laserID;
laserID = p_DiagIF->GetLaserID();
LCP_V = laserID->m_LCPSoftwareVersion;
FCP_V = laserID->m_FCPSoftwareVersion;
strcpy(LCP_Version, LCP_V.c_str());
strcpy(FCP_Version, FCP_V.c_str());
return return_status;
}
1 Answer
You're getting the error OSError: exception: access violation writing 0x00000000 because of the statement LCP_Version = ct.c_char_p(0). As suggested by the ctypes documentation for c_char_p you're passing an integer address.
What you're telling ctypes to do is make a new char * pointing to 0, then trying to strcpy to it via strcpy(LCP_Version, LCP_V.c_str());. If you were to use ct.c_char_p(1), you'd get access violation writing 0x0000001, if c_char_p(2), then at 0x...2, and so on. It's very unlikely that your memory should or will want to allow you to write to that location, hence the error.
What you likely want to do is use create_string_buffer(N), where N is the size of the array needed to contain the output of LCP_V = laserID->m_LCPSoftwareVersion;. create_string_buffer, as the name suggests, will give you a mutable char buffer that's initialized to null bytes (e.g. p = create_string_buffer(3) means p is size 3, with contents b'\x00\x00\x00). You could guess and check or look at the source of p_DiagIF->GetLaserID(); to hunt down the safe value of N, or just give yourself something huge (for a version number) like LCP_Version = ct.c_char_p(50) and pick something sane from there.