Md23 Ответов: 2

Как изменить VB.NET структура, переданная в библиотеку DLL C++


I need to pass a structure from VB.NET program to C++ program in order to modify the members of the structure. 

I had the DLL set up and working in my VB.Net program before the need to modify the structure but I needed to.

Here is how I define the DLL in VB.NET


Что я уже пробовал:

<DllImport("ConvertRaw.dll", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function OpenRawFile(<MarshalAs(UnmanagedType.LPStr)> x As String, ByRef CurrentStamp As RawDataHeader) As Integer
End Function


Вот такая структура в VB.NET

Public Structure RawDataHeader
   Public syncpattern As Integer
   Public runnumber As As Integer
   Public muxpitch As Integer
   Public ThisChannel() As Integer
  End Structure


Вот структура в c++
typedef struct {
   int      syncpattern;                        
   int      run;                            
   int      datastream;
   std::vector<int> channels;                 
  }RawDataHeader;


Вот код c++
MYDLL_API int OpenRawFile(const char* fileName, RawDataHeader &stamp)
{

   long offset;
   long size;

   pfile.open(fileName, ios::binary);
   //long myDataStampSize = GetDataStampSize();
   if (!pfile.is_open())
   {
      std::cout << "ERROR";
   }

   pfile.seekg(0, pfile.end);
   length = pfile.tellg();
   pfile.seekg(0, pfile.beg);
   offset = length - stampSize;

      // Start from the end and read
   pfile.seekg(0, pfile.end);
   pfile.seekg(-4, pfile.end);
   pfile.read((char*)&numChannels, sizeof(numChannels));

   stamp.channels.resize(numChannels);

   pfile.seekg(offset, pfile.beg);
   pfile.read((char*)&stamp.syncpattern, sizeof(int));
   pfile.read((char*)&stamp.run, sizeof(int));
   pfile.read((char*)&stamp.datastream, sizeof(int));

   for (int i = 0; i < numChannels; i++)
   {
      pfile.read((char*)&stamp.channels[i], sizeof(int));
   }

    pfile.close();
   return 0;
}


Это создает исключение:
Исключение, вызванное в 0x0F068B47 (ConvertRaw.dll) в ConsoleApp3.exe: 0xC0000005: нарушение доступа к местоположению чтения 0x0000000C.

Я решил, что это как-то связано с вектором. Я переделываю в VB.Сеть для того, чтобы установить размер каналов. Что я упускаю?

Afzaal Ahmad Zeeshan

Делает этот - помочь?

Gerry Schmitz

https://docs.microsoft.com/en-us/dotnet/api/system.io.binarywriter?view=netframework-4.8

Md23

Зачем использовать двоичный писатель?

Gerry Schmitz

Выравнивание.

2 Ответов

Рейтинг:
2

KarstenK

Проблема заключается в смешивании строки и массива символов. Вы не можете проверить это, комментируя эти поля.

Я бы использовал какой-нибудь char или байтовый массив или когда вы хотите вложить некоторые усилия в эту проблему: a _bstr_t.

PS: я прочитал решение 2 Дэйва К., и он абсолютно прав. Длинный ОГ VB.net это 8 байт большой, и поэтому размер не соответствует 4 байтам целого числа C++. Вам тоже нужно заняться этим вопросом.


Md23

Я попытался прокомментировать их, но все равно получил тот же результат

KarstenK

Прочтите мои добавленные ps-замечания и решение 2. Вам нужно обратиться к нему.

Md23

Я сделал то же самое но все еще безуспешно

Md23

Я попробовал это сделать но все равно безуспешно

Рейтинг:
2

Dave Kreskowiak

МММ...ваши структуры не совпадают.

Один Long в VB.NET является 64-битным целым числом со знаком (8 байт), в то время как соответствующая переменная в структуре C++ является int, который является 32-разрядным целым числом со знаком (4 байта). Если я не ошибаюсь, соответствующий 64-битный целочисленный тип в C++ должен быть long long (да, их было двое).


Md23

Итак, то, что вы говорите, находится в VB.net код там, где когда - либо есть длинный c++ должен иметь длинный длинный? Так как длина составляет 8 байт в VB.NET а int-это 4 байта в c++

KarstenK

Вы можете использовать целочисленный тип данных VB.

Md23

Хорошо. Я изменил все длинные числа на целые, но все равно получил то же исключение.

Md23

Как вы думаете, вектор-это проблема?