“WindowsError: исключение: нарушение прав доступа …” - ctypes вопрос

Нет опции для него. В Java (как многие другой Ленг.) у Вас может быть доступ ко всем статическим членам класса через его имя класса или объект экземпляра того класса. Это было бы ваше дело и Ваш случай и программный продукт, какой необходимо использовать, который дает Вам больше удобочитаемости.

5
задан Community 23 May 2017 в 10:27
поделиться

2 ответа

Ошибка, которую вы получаете, не связана с правами администратора. Проблема в том, что вы используете C и непреднамеренно выполняете недопустимые операции (операции, которые, если их не отметить, могут привести к сбою вашей системы).

Полученная вами ошибка указывает на то, что ваша программа пытается записать по адресу 1001, но не предполагается, что запись по этому адресу памяти.

Это может произойти по любому количеству причин.

Одна из возможных причин заключается в том, что двойной *, который вы передаете ReturnPulse, не такой большой, как того ожидает ReturnPulse. быть. Вероятно, вам нужно хотя бы заставить GetSize работать должным образом ... вы можете обойти это, просто выделив очень большой массив вместо вызова GetSize. т.е.

ptrfdP = (c_double*100000)()

Это выделит 100 000 дублей, что может быть более подходящим для захвата цифрового импульса.

Другая проблема заключается в том, что преобразование типа может происходить не так, как ожидалось.

Вам может повезти больше, если ctypes знает, что ReturnPulse принимает пять двойных указателей. т.е.

# sometime before calling ReturnPulse
FROGPCGPMonitorDLL.ReturnPulse.argtypes = [POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double)]

Если ни один из этих методов не работает, отправьте документацию по использованию на ReturnPulse, которая должна помочь нам распознать предполагаемое использование.

Или еще лучше, отправьте образец кода, который должен работать на C, и я переведу его на эквивалентная реализация в ctypes.

Edit: добавление примера реализации ReturnPulse и использования ctypes.

Я реализовал что-то вроде того, что я ожидал от ReturnPulse в C DLL:

void ReturnPulse(double *a, double*b,double*c,double*d,double*e)
{
    // write some values to the memory pointed-to by a-e
    // a-e should have enough memory allocated for the loop
    for(int i = 0; i < 20; i++)
    {
        a[i] = 1.0*i;
        b[i] = 3.0*i;
        c[i] = 5.0*i;
        d[i] = 7.0*i;
        e[i] = 13.0*i;
    }
}

Я компилирую это в DLL ( который я называю exclib), а затем вызываю его, используя ctypes со следующим кодом:

LP_c_double = ctypes.POINTER(ctypes.c_double)
examlib.ReturnPulse.argtypes = [LP_c_double, LP_c_double, LP_c_double, LP_c_double, LP_c_double, ]

a = (ctypes.c_double*20)()
b = (ctypes.c_double*20)()
c = (ctypes.c_double*20)()
d = (ctypes.c_double*20)()
e = (ctypes.c_double*20)()

examlib.ReturnPulse(a,b,c,d,e)

print 'values are'
for array in (a,b,c,d,e):
    print '\t'.join(map(str, array[:5]))

В результате получается

values are
0.0     1.0     2.0     3.0     4.0
0.0     3.0     6.0     9.0     12.0
0.0     5.0     10.0    15.0    20.0
0.0     7.0     14.0    21.0    28.0
0.0     13.0    26.0    39.0    52.0

В самом деле,

12
ответ дан 13 December 2019 в 05:39
поделиться

Причина в том, что заключенный () внутри makebold не принимает никакие аргументы.

Когда вы используете декоратор так, что это может вызвать некоторые проблемы, я опубликую пример того, как достичь того, что вы хотите, хотя, дайте мне только минуту.

Вот рабочий пример того, что вам нужно.

def makebold(rewrap=False):
    if rewrap:
        def inner(decorator):
            def rewrapper(func):
                def wrapped(*args, **kwargs):
                    return "<b>%s</b>" % decorator(func)(*args,**kwargs)
                return wrapped
            return rewrapper
        return inner

    else:
        def inner(func):
            def wrapped(*args, **kwargs):
                return "<b>%s</b>" % func(*args, **kwargs)    
            return wrapped
        return inner

@makebold(rewrap=True)
def makeitalic(fn):
    def wrapped(*args, **kwargs):
        return "<i>%s</i>" % fn(*args, **kwargs)
    return wrapped

@makeitalic
def hello():
    return "hello world"

@makebold()
def hello2():
    return "Bob Dole"    

if __name__ == "__main__":
    print hello()   
    print hello2()

makebold немного уродлив, но он показывает, как написать декоратор, который может опционально обернуть другой декоратор.

Вот выходные данные приведенного выше сценария:

<b><i>hello world</i></b>
<b>Bob Dole</b>

Обратите внимание, что makebold является единственным рекурсивным декоратором. Также обратите внимание на тонкую разницу в использовании: @ makebold () против @ makeitalic .

-121--3665366-

Это также работает:

/*
 * code.c
 */
#include <stdio.h>

void printArray(int **iXArray, int iSize);

int main() {
    int array1[] = {7, 9, 3, 18};
    int *array2[] = {array1 + 0, array1 + 1, array1 + 2, array1 + 3};

    printArray(array2, 4);

    return 0;
}

// This should print the values in array1
void printArray(int **iXArray, int iSize) {
    int iCntr;
    for (iCntr = 0; iCntr < iSize; iCntr++) {
            printf("%d ", *iXArray[iCntr]);
    }
    printf("\n");
}

Арифметика указателя работает отлично.

-121--4716524-

ptrpulse и друзья являются идентификаторами python, которые указывают на различные объекты ctypes (я полагаю, что все они c_double*2). Их необходимо либо обернуть с помощью объекта указателя ctypes, либо передать функции C с помощью ctypes.byref.

0
ответ дан 13 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

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