#c# #c #.net-3.5 #dllimport
#c# #c #.net-3.5 #dllimport
Вопрос:
Я создал DLL-функцию для использования внутри C # с использованием DllImport, но у меня возникли проблемы с вызовом метода, поскольку у меня возникают проблемы с повреждением памяти;
[DllImport("mydll.dll", EntryPoint = "callinmydll")]
public static extern int testdllcall(double *firstinput, long firstcount, double *secondoutput, long secondcount);
Вот часть заголовка библиотеки C ;
extern "C" {
mydll_API int callinmydll(double *in, long firstcount, double *out, long secondcount);
}
Реализация.
mydll_API int callinmydll(double *in, long firstcount, double *out, long secondcount)
{
for( int i =0 ; i < 10 ; i )
{
*(out i) = (*(in i) 10 );
}
return 0;
}
Теперь, когда моя функция DllImport вызывает функцию callinmydll и передает ей действительные данные, вот тут все становится интересным. Указатель in содержит данные, как и firstcount . Хотя все, что находится за пределами этой точки, повреждено. Почему? Любопытно, что я перестраиваю свою функцию на double, double *, long, long теперь повреждение происходит после третьего параметра. Мне любопытно, что происходит, поскольку я передаю действительные данные; два действительных указателя и приведение int к int64.
Помогите!
Комментарии:
1. Не совсем уверен, но это не long в c , больше похоже на int в c #, т.е. от -2147483647 до 2147483647
2. Соглашения о вызовах также не совпадают.
Ответ №1:
В Win32 C a long
по-прежнему 32-разрядный. В вашей подписи C # используется long
64-разрядный код. Ваш второй и четвертый параметры должны быть int
в сигнатуре C #.
Смотрите Эту таблицу для получения дополнительной информации.
Итак, ваша подпись выглядит так:
[DllImport("mydll.dll", EntryPoint = "callinmydll")]
public static extern int testdllcall(double *firstinput, int firstcount, double *secondoutput, int secondcount);
Кроме того, убедитесь, что ваше соглашение о вызовах правильное, как указал Ramhound в комментариях. Ваша функция C выглядит так, как будто она использует соглашение CDecl, а .NET по умолчанию использует StdCall . Вы можете установить соглашение о вызовах в атрибуте:
[DllImport("mydll.dll", EntryPoint = "callinmydll", CallingConvention = CallingConvention.Cdecl)]
Комментарии:
1. Спасибо за ответ, теперь имеет смысл.
2. Если управляемый код предназначен для запуска в 32-разрядной или 64-разрядной среде Windows, то как следует использовать ДЛИННЫЙ параметр?
3. Предполагая, что «ДЛИННЫЙ» означает Win32 long, его следует маршалировать как
int
.