Вызов кода C ++ из ошибки C # с использованием ссылок в C ++

0

В моей C++ dll с именем "scandll.dll" у меня есть следующая функция

extern "C" __declspec(dllexport) void scanfile(char * returnstring)
{
    strcpy(returnstring, "return string");
}

в моем коде С# я делаю это

[DllImport("scandll.dll", CharSet = CharSet.Ansi, SetLastError = true )]
public static extern int scanfile(ref IntPtr strReturn);

и это метод, который я использую для получения значения из dll

public void Scan()
{
     string filename = "";
     IntPtr ptr = new IntPtr();
     scanfile(ref ptr);//Here i get the error
     filename = Marshal.PtrToStringAnsi(ptr);
}

Я получаю исключение, которое вызывается как "Попытка читать или записывать защищенную память. Это часто свидетельствует о том, что другая память повреждена".

Я следую этой ссылке

Вызов кода C++ с ошибкой С# с использованием ссылок в C++ ref в С#

Любая помощь будет оценена по достоинству.

благодаря

  • 1
    Ваша функция C уже неверна. Зачем вам нужна функция C, когда у вас возникают проблемы при ее написании? Вы не можете использовать управляемую функцию?
  • 0
    Установка CharSet.Ansi ничего не делает, когда вы вручную сортируете строки. Фактически, в этом конкретном случае это может замедлить вызов, потому что среда выполнения будет искать scanfileA перед поиском scanfile
Показать ещё 2 комментария
Теги:
dllimport

2 ответа

4

Ваш код C++ неправильный - все, что он делает, это изменение значения указателя, которое было передано ему, чтобы указать на константную строку. Вызывающий не знает ничего об этом изменении.

Это так же, как если бы вы сделали это:

void MyCfunction(int number)
{
   number = 3;
}

и затем надеялся, что вызывающая сторона этой функции каким-то образом увидит номер "3" где угодно.

Вы можете сделать что-то подобное в C++:

void MyCFunction(char* pReturnString)
{
 strcpy(pReturnString, "Hello, world");
}

но вам также необходимо убедиться, что на стороне С# вы предоставили буфер с указанием pReturnString. Один из способов сделать это с помощью StringBuilder, а затем с вашим объявлением С# функции C принять такой параметр:

[MarshalAs(UnmanagedType.LPStr)] StringBuilder returnString

Перед вызовом функции C++ вам необходимо зарезервировать место в StringBuilder.

В реальной жизни C/C++ функционирует так, как это почти всегда принимает параметр дополнительной длины, который позволяет вызывающему абоненту сообщать вызываемой стороне максимальную длину строки, которую она разрешает копировать в буфер. Не существует согласованности с соглашением о том, включает ли длина завершающий \0 или нет, поэтому люди часто стараются работать до самого конца буфера.

0
  memcpy (  destination,  * source, size_t num );

Попробуйте присвоить значение returnstring = "rturn name";

  • 0
    Я забыл добавить strcpy. Но все же я застрял с той же проблемой. Я получаю ту же ошибку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню