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 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

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.

Share this article
Twitter Facebook Pinterest