Как правильно сделать Dllimport в c #? - PullRequest
0 голосов
/ 12 апреля 2011

У меня были некоторые проблемы с созданием правильного .dll из c ++ - проекта в мой c # -проект.Я поиграл с c ++ - project-properties и получил файл .dll, который я могу добавить и сослаться в моем c # web-проекте.Я использую Dllimport для вызова функции .dll следующим образом:

[DllImport("Filename.dll", CharSet = CharSet.Ansi)]
static extern void Function1([MarshalAs(UnmanagedType.LPStr)] string src, 
                             int srcLen, 
                             [MarshalAs(UnmanagedType.LPWStr)] StringBuilder dst,
                             int dstLen)

Заголовок функции c ++:

__declspec(dllimport) void Function1(unsigned char *src, 
                     unsigned long srclen, 
                     unsigned char *dst, 
                     unsigned long dstlen);

Я вызываю Function1 в c # с помощью этого:

string strSrc = "Something";
StringBuilder strDest = new StringBuilder(kryptlen-1);
int l = strSrc.Length();
Function1(strSrc, l, strDest, l);

Никаких исключений или ошибок не происходит, хотя я не получаю ожидаемый результат.Функция представляет собой метод расшифровки, который принимает зашифрованную строку (src) и возвращает расшифрованную версию этого (dst).

Это способ, которым я сгенерировал файл .dll, или это неправильный способ, которым я вызываюфункционировать?У меня заканчиваются идеи, которые я пробовал в большинстве комбинаций.

Спасибо за совет!

Ответы [ 3 ]

2 голосов
/ 12 апреля 2011

C ++ по умолчанию, если не изменено, используется соглашение о вызовах вызывающей стороны (Cdecl).Ваш код C ++ не меняет соглашение о вызовах.Ваш код C # по умолчанию (если вы его не измените) будет использовать соглашение вызываемого абонента (StdCall).

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

Нет исключений или ошибок, хотя я не получаю ожидаемый результат.Функция представляет собой метод дешифрования, который принимает зашифрованную строку (src) и возвращает расшифрованную версию этого (dst).

Что именно вы получаете?

Решение проблемыПроблема соглашения о вызове заключается в объявлении соглашения о вызове.

[DllImport("Filename.dll", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] static extern void Function1([MarshalAs(UnmanagedType.LPStr)] string src,                               int srcLen,                               [MarshalAs(UnmanagedType.LPWStr)] StringBuilder dst,                              int dstLen) 
2 голосов
/ 12 апреля 2011

Откуда взялся UnmanagedType.LPWStr?В объявлении C ++ нет широких строк.Вы также передаете длину источника дважды, в то время как имена переменных предполагают, что вам нужна длина источника и емкость буфера назначения.

Если, как вы говорите, src - это зашифрованные данные, правильная сигнатура p / invoke:вероятно:

[DllImport("Filename.dll", CallingConvention = CallingConvention.CDecl)]
static extern void Function1(byte[] src, 
                             UInt32 srcLen,
                             [MarshalAs(UnmanagedType.LPStr)] StringBuilder dst,
                             UInt32 dstLen)

Попытка форсировать двоичные данные в строку Unicode - проигрышное предложение.

1 голос
/ 20 апреля 2011

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

Это конечная настройка, с которой я застрял, надеюсь, она кому-нибудь поможет:

...