AccessViolationException и MSSQL 2005
От: sivachenko  
Дата: 02.02.07 13:55
Оценка:
Привет, не могли бы вы помочь разобраться с проблемой, все пересмотрел, не как не могу понять причину.

Пишу хранимую процедуру на 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); 
                    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.