|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Здравствуйте, У меня просьба проверить синтаксис, так как программа ругается сообщением: автор"A call to PInvoke function 'TestApplicationForMP!TestApplicationForMP.MP_API::PSE31_Generation' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature." Причем ругается и на PSE31_Generation и на Copy_PSE31 Думаю, что неправильно объявил декларацию функций, но сообразить где проблема, не могу есть сишная библиотека, в которой объявлены: автор/* Initialization and Completion Functions */ MPFUN int MPAPI PKCS7Init(char *pse_path, int reserved); MPFUN int MPAPI PKCS7Final(void); /* Key and Certificate Request Generation Functions */ MPFUN int MPAPI PSE31_Generation(char *pse_path, int reserv1, char *reserv2, unsigned long flags); MPFUN int MPAPI Copy_PSE31(char *pse_path, char *reserv, char *new_pse_path, unsigned long flags); Я написал следующую обертку для dll: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
Пытаюсь применить следующим образом: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2007, 17:25 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Если это старя библиотека, то тип int там может быть 16 разрядным, а long 32 разрядным. Соответственно объявления функций надо записать так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2007, 17:53 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
пасиб, так не ругается ))) удивительно, dll скомпилирована в 2005 году, а разрядность старая ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2007, 18:07 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79пасиб, так не ругается ))) удивительно, dll скомпилирована в 2005 году, а разрядность стараяbazile Вам подсказал верное направление... но не до конца. Сишным 32-битным типам int и unsigned long будут соответствовать c#-ные int и uint. Кроме того, если Ваши сишные функции пишут что-то по указателям на char, то на C# такие параметры следует объявить как StringBuilder, а не string. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2007, 18:33 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
учту, хотя StringBuilder - необычно для меня, всегда считал, что это довольно таки сложный класс, и как его можно подставить в параметр как простой указатель на строку - непонятно Может сделаете еще доброе дело и объясните, как в С# представить параметр void? Код: plaintext
... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2007, 19:27 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
void не может быть параметром, а вот void* это нетипизированный указатель или IntPtr в С#. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2007, 20:04 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79учту, хотя StringBuilder - необычно для меня, всегда считал, что это довольно таки сложный класс, и как его можно подставить в параметр как простой указатель на строку - непонятноСмысл в том, что если Ваша нативная функция берет char *, который указывает на некоторую область памяти, заранее Вами выделенную, и что-то туда пишет, то такой параметр char * следует представлять как StringBuilder, а перед вызовом такой функции этот StringBuilder нужно создать, причем указать нужный (достаточный) размер. Почему так - строки (string) в .NET - это неизменяемые объекты, а для StringBuilder дотнетовский маршаллер имеет специальную встроенную поддержку. Если же нативная функция не изменяет память, указываемую параметром char *, то можно писать просто string. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2007, 11:34 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
long longВот еще это поглядите на предмет интеропа и строковых параметров, там все подробно рассказано. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2007, 11:44 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
bazilevoid не может быть параметром, а вот void* это нетипизированный указатель или IntPtr в С#. Я к чему спрашивал - вижу такое объявление: Код: plaintext
именно void без дополнительных символов я в Си не очень разбираюсь, поэтому сакральный смысл этого объявления оставался для меня скрыт long longСмысл в том, что если Ваша нативная функция берет char *, который указывает на некоторую область памяти, заранее Вами выделенную, и что-то туда пишет, то такой параметр char * следует представлять как StringBuilder, а перед вызовом такой функции этот StringBuilder нужно создать, причем указать нужный (достаточный) размер. Почему так - строки (string) в .NET - это неизменяемые объекты, а для StringBuilder дотнетовский маршаллер имеет специальную встроенную поддержку. Если же нативная функция не изменяет память, указываемую параметром char *, то можно писать просто string. Большое спасибо long longВот еще это поглядите на предмет интеропа и строковых параметров, там все подробно рассказано. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.07.2007, 14:02 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79Я к чему спрашивал - вижу такое объявление: Код: plaintext
именно void без дополнительных символов я в Си не очень разбираюсь, поэтому сакральный смысл этого объявления оставался для меня скрыт Такое объявление говорит что функция PKCS7Final не принимает параметров. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.07.2007, 14:11 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Позволю себе продолжить свой ликбез и послушать умных людей есть ф-ция MPFUN int MPAPI GetSignatureCertInBuffer(void *ctx, int ind, char **buf, int *ln); про void *ctx я понял, что это IntPtr ctx, так же как и int *ln = IntPtr ln но как же **? Все равно стрингбилдер (StringBuilder buf)? И как же тогда пользоваться такой функцией? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 16:47 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Тип параметра char** означает массив строк. Судя по информации из MSDN (смотри объявление функции TestArrayOfStrings) тип параметра в .NET должен быть [In, Out]string[] buf ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 17:01 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79Позволю себе продолжить свой ликбез и послушать умных людей есть ф-ция MPFUN int MPAPI GetSignatureCertInBuffer(void *ctx, int ind, char **buf, int *ln); про void *ctx я понял, что это IntPtr ctx, так же как и int *ln = IntPtr ln но как же **? Все равно стрингбилдер (StringBuilder buf)? И как же тогда пользоваться такой функцией?int *ln - это ref int ln, если *ln не может быть null char **buf - это ref IntPtr buf, если **buf не может быть null, или просто IntPtr buf, если может. Тут StringBuilder, имхо, не поможет. В последнем случае, кроме того, придется повозиться дополнительно, но непреодолимых препятствий нет. Посмотрите в MSDN про класс Marshal и GCHandle ПС. Также посмотрите на pinvoke.net, возможно, есть какие-либо системные функции с похожими сигнатурами... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 17:05 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
bazileТип параметра char** означает массив строк. Судя по информации из MSDN (смотри объявление функции TestArrayOfStrings) тип параметра в .NET должен быть [In, Out]string[] buf pinvokeint *ln - это ref int ln, если *ln не может быть null char **buf - это ref IntPtr buf, если **buf не может быть null, или просто IntPtr buf, если может. Тут StringBuilder, имхо, не поможет. В последнем случае, кроме того, придется повозиться дополнительно, но непреодолимых препятствий нет. Посмотрите в MSDN про класс Marshal и GCHandle ПС. Также посмотрите на pinvoke.net, возможно, есть какие-либо системные функции с похожими сигнатурами... имеет значение char** или char **? buf есть указатель на указатель на буфер с сертификатом. Буфер может быть выделен пользователем заранее или внутри данной функции. В последнем случае указатель на буфер должен быть равен NULL. Освобождение выделенного буфера осуществляется функцией FreeBuffer И какое объявление верное? PS Чертов С, в Delphi все гораздо гораздо проще :) Или привычнее... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 18:18 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79имеет значение char** или char **? Не имеет. Это одно и тоже. Arm79И какое объявление верное? У тебя есть описание что делает функция GetSignatureCertInBuffer? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 18:31 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
bazile Arm79имеет значение char** или char **? Не имеет. Это одно и тоже. Arm79И какое объявление верное? У тебя есть описание что делает функция GetSignatureCertInBuffer? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 18:33 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79Buf - указатель на указатель на буфер с сертификатом. Буфер может быть выделен пользователем заранее или внутри данной функции. В последнем случае указатель на буфер должен быть равен NULL. Освобождение выделенного буфера осуществляется функцией FreeBuffer. Len - указатель на размер выделенного пользователем буфера Buf (перед вызовом функции). Игнорируется, если Buf равен NULL. После возврата функции - указатель на длину сертификата в буфере.Как я и предполагал, char** в данном случае - это не массив строк, а значит, объявление string[] buf, к сожалению, не покатит. Придется все-таки писать ref IntPtr buf. Дальше зависит от того, будете ли Вы сами выделять буфер - то ли с помощью byte[] buffer = new byte[bufferSize]; GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); IntPtr buf = h.AddrOfPinnedObject(), то ли с помощью IntPtr buf = Marshal.AllocHGlobal(bufferSize) - первый вариант сложнее, но не требует копирования памяти, второй вариант потребует использования Marshal.Copy(), или доверите это Вашей с-шной функции - IntPtr buf = IntPtr.Zero. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 18:55 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
pinvoke Arm79Buf - указатель на указатель на буфер с сертификатом. Буфер может быть выделен пользователем заранее или внутри данной функции. В последнем случае указатель на буфер должен быть равен NULL. Освобождение выделенного буфера осуществляется функцией FreeBuffer. Len - указатель на размер выделенного пользователем буфера Buf (перед вызовом функции). Игнорируется, если Buf равен NULL. После возврата функции - указатель на длину сертификата в буфере.Как я и предполагал, char** в данном случае - это не массив строк, а значит, объявление string[] buf, к сожалению, не покатит. Придется все-таки писать ref IntPtr buf. Дальше зависит от того, будете ли Вы сами выделять буфер - то ли с помощью byte[] buffer = new byte[bufferSize]; GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); IntPtr buf = h.AddrOfPinnedObject(), то ли с помощью IntPtr buf = Marshal.AllocHGlobal(bufferSize) - первый вариант сложнее, но не требует копирования памяти, второй вариант потребует использования Marshal.Copy(), или доверите это Вашей с-шной функции - IntPtr buf = IntPtr.Zero. Пасиб за консультацию ))). Думаю, IntPtr buf = IntPtr.Zero - самое то ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2007, 19:33 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Может порекомендуете ресурсы/книги/статьи по работе с P/Invoke? И по использованию в C# unmanaged code? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 10:02 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79Может порекомендуете ресурсы/книги/статьи по работе с P/Invoke? И по использованию в C# unmanaged code?В C# "unmanaged code" нет в принципе, есть unsafe - это разные вещи. Насчет ресурсов - в MSDN полно примеров интеропа, а на pinvoke.net - сигнатуры очень многих апишных функций и сопутствующих структур на C# (правда, не всегда удачных, но это поправимо руками). Основные средства при интеропе - MarshalAsAttribute, StructLayoutAttribute, FieldOffsetAttribute, Marshal и GCHandle, да еще ключевое слово fixed в unsafe режиме. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 10:41 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
А еще вопросики можно? ) Есть: Для встраивания библиотеки в Вашу программу (проект) выполните следующее: - задайте макроопределения MP_DLL и USE_INIT_FLAG; А как на C# задавать макроопределения? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 14:44 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Задавать-то их можно при помощи #define. Только в C# проекте приведённые Вами определения нужного влияния не окажут. Я так понимаю, эти определения - пользовательские и будут использованы только при компиляции исходников этой библиотеки криптования. А Вы используете уже скомпилированную библиотеку. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 15:02 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79А как на C# задавать макроопределения?А никак. Импорт функций и структур возможен только руками (в случае с COM-dll при наличии библиотек типов можно автоматически сгенерировать interop-обертки). ЗЫ. Если Вас интересуют т.н. preprocessor definitions, то задаются они также - с помощью #define, только в Вашем случае они ничем не помогут. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 15:05 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Arm79А как на C# задавать макроопределения? Практически также как и в C/C++:#define ИМЯ. Отличие в том, что нельзя присвоить этому имени значение как в препроцессоре С/С++. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 15:06 |
|
взаимодействие с сишной библиотечкой крипотования
|
|||
---|---|---|---|
#18+
Мир не без добрых людей :) Пасиб. Самаритяне, поясните недалекому: есть MPFUN void MPAPI SetRandInitCallbackFun(void *Func); Данная функция задает пользовательскую функцию обратного вызова RandInitCallback, которая вызывается из библиотеки для инициализации генератора случайных чисел. Func - указатель на функцию RandInitCallback, реализованную в пользовательском приложении. Описание функции RandInitCallback следующее: int _stdcall RandInitCallback(int c, int step, int from, char *reserv); c – символ, который должен ввести пользователь (должен отображаться на экране); step – номер текущей итерации; from – общее число итераций; reserv – не используется. Функция RandInitCallback возвращает код введенного пользователем символа (может не совпадать с требуемым символом, в этом случае номер итерации будет уменьшен). Если функция RandInitCallback возвращает -1, процедура инициализации прерывается. Вызов функции RandInitCallback в Windows приложениях осуществляется по правилам языка Pascal (_stdcall). Пример реализации функции RandInitCallback: int _stdcall RandInitCallback(int c, int step, int from, char *reserv) { unsigned char cc[64]; fprintf(stdout, "Step=%2i/%2i Press %c [%02x]: ", step, from, c, c); fgets((char *)cc, sizeof(cc), stdin); if(strcmp((char *)cc, "\n") == 0) return -1; return *cc; } почитав .NET Framework Developer's Guide How to: Implement Callback Functions сделал: Код: plaintext
а в классе: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Применяю: Код: plaintext 1.
и не работает :) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2007, 17:07 |
|
|
start [/forum/topic.php?fid=20&startmsg=34671160&tid=1400352]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
44ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
63ms |
get tp. blocked users: |
2ms |
others: | 282ms |
total: | 436ms |
0 / 0 |