Привет, не могли бы вы помочь разобраться с проблемой, все пересмотрел, не как не могу понять причину.
Пишу хранимую процедуру на C#, она должна вызывать неуправляемый код из .dll.
При работе процедуры вылетает исключение AccessViolationException.
Похоже что вылетает при передаче параметров.
Такой же точно код, как и в хранимой процедуре, нормально работает в отдельном приложении.
Никаких исключений не вылетает (трассировал в VC со всеми включенными исключениями).
Исходные данные одни и те же, библиотека .dll отлажена абсолютно.
Нужно передать массивы в библиотеку и в них же получить результат.
Библиотека указатели не меняет, только изменят данные в памяти.
ref или out вроде как не нужны т.к. идея такая: выделяем в .NET область памяти, передаем укзатель на неё,
под данному адресу меняем данные, возвращаемся назад в .NET и всё должно быть ОК.
Код хранимой процедуры:
[DllImport("TSA.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void iInitNOS(
float[] Other,
float[] Realiz,
float[] Rest,
float[] Supply,
ushort[] NosStats,
ushort ToDay,
float NosConfidence,
byte[] Nos,
byte[] Presence);
[Microsoft.SqlServer.Server.SqlProcedure]
public static void CalcNos(int id_dep, int id_item)
{
_сurItemMove.Realiz = new float[length];
_сurItemMove.Supply = new float[length];
_сurItemMove.Rest = new float[length];
_сurItemMove.Other = new float[length];
<В описанные выше массивы читаются данные из БД длины length>
//массивы для результатов
_сurItemMove.Nos = new byte[length];
_сurItemMove.Presence = new byte[length];
// параметры
ushort[] _NosStats = new ushort[3];
_NosStats[0] = 0;
_NosStats[1] = 0;
_NosStats[2] = 0;
float _NosConfidence = (float)0.01;
ushort _ToDay = (ushort)(length - 1);
iInitNOS(_сurItemMove.Other,
_сurItemMove.Realiz,
_сurItemMove.Rest,
_сurItemMove.Supply,
_NosStats,
_ToDay,
_NosConfidence,
_сurItemMove.Nos,
_сurItemMove.Presence);
}
Заголовок в библиотеке на с++:
__declspec(dllexport) void __cdecl iInitNOS(
float *Other, float *Realiz, float *Rest, float *Supply,
unsigned short *NosStats,
unsigned short ToDay, float NosConfidence,
char *Nos, char *Presence)
{
//меням данные в памяти по адресам Nos, Presence
}
пробовал ещё так:
[DllImport("TSA.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe void iInitNOS(
float* Other,
float* Realiz,
float* Rest,
float* Supply,
ushort* NosStats,
ushort ToDay,
float NosConfidence,
byte* Nos,
byte* Presence);
unsafe
{
fixed (
float* Other = _сurItemMove.Other,
Realiz = _сurItemMove.Realiz,
Rest = _сurItemMove.Rest,
Supply = _сurItemMove.Supply)
fixed (ushort* pNosStats = _NosStats)
fixed (byte* Nos = _сurItemMove.Nos, Presence = _сurItemMove.Presence)
{
iInitNOS(Other,
Realiz,
Rest,
Supply,
pNosStats,
(ushort)_ToDay,
_NosConfidence,
Nos,
Presence);
}