Ошибка чтения / записи при попытке использовать метод из внешней библиотеки - PullRequest
1 голос
/ 19 февраля 2020

Я пытаюсь использовать следующую реализацию из библиотеки

enter image description here

C ++

int CALLBACK xCallback(long xmitlen, int buflen, char *buf, long flen)
{
    return 0;
}

extern "C"  __declspec(dllexport) int __stdcall TXFIlestransfer(int port, string fileName);

__declspec(dllexport) int __stdcall TXFIlestransfer(int port, string fileName)
{
     int ret;

     char *test = &fileName[0];

     ret = sio_FtKermitTx(port, test, xCallback, 27);

     return ret;
}

Я импортирую это для использования с C# и получаю System.AccessViolationException: 'Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена. '

enter image description here

Любая помощь в устранении этой ошибки будет принята с благодарностью.

1 Ответ

2 голосов
/ 19 февраля 2020

Я протестировал вашу программу, имитируя функцию sio_FtKermitTx в моем C ++ dll ( Mydll.dll ):

int sio_FtKermitTx (int port, char *fname, int (CALLBACK *func) (long xmitlen, int buflen, char *buf, long flen), int key)
{
    return 5;
}

И даже с пустым телом, я У меня та же проблема, что и у вас.

После нескольких исследований я заметил, что проблема возникла из-за того, что мы используем объект string между C# и C++ кодом, который для одного причина или другая (например, конфигурация Unicode / Multibyte или просто потому, что совместное использование сложных объектов сложно реализовать) вызывает проблемы.

Решение:
При замене объекта string на примитивный тип char все работает правильно:

C# Код:

using System.Runtime.InteropServices;
namespace MyProgramme
{
    class Test
    {
        // Import C++ DLL
        [DllImport("Mydll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int TXFIlestransfer(int i, char[] filename);
        //public static extern int TXFIlestransfer(int i, string filename); // this crash

        static void RunTest(/*LoadFilterEVENTMessage msg*/)
        {
            string c = "ABC";
            char[] char_arr = c.ToCharArray();
            int i = TXFIlestransfer(3, char_arr);
            // int i = TXFIlestransfer(3, c); string version crash

            string s = i.ToString();
            MessageBox.Show(s);
        }

        /* Methods in DLL being used below  */
        public static void Main()
        {
            RunTest();
        }
    };
}

C ++ DLL-код (Mydll.dll):

extern "C" __declspec(dllexport) int TXFIlestransfer(int port, char fileName[])
{
    int ret;
    char *test = &fileName[0];
    ret = sio_FtKermitTx(port, test, xCallback, 27);
    return ret;
}

в любом случае, ваша sio_FtKermitTx функция принимает char* в параметре поэтому изменение параметров TXFIlestransfer с string на char[] не составляет проблем c.

Результат:
После запуска программы C# вы получите это :

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...