Проблемы манипулирования строками через stdcall в dll - PullRequest
0 голосов
/ 16 ноября 2011

Мне нужно создать C ++ dll, который будет вызываться из другой программы через stdcall.

Что необходимо: вызывающая программа передаст массив строк в dll, а dll должна изменить строковые значения в массиве. Затем программа-вызывающая программа продолжит работать с этими строковыми значениями, полученными из библиотеки DLL.

Я сделал простой тестовый проект, и мне явно что-то не хватает ...

Вот мой тест C ++ dll:

#ifndef _DLL_H_
#define _DLL_H_

#include <string>
#include <iostream>

struct strStruct
{
    int len;
    char* string;
};

__declspec (dllexport) int __stdcall TestFunction(strStruct* s)
{
   std::cout << "Just got in dll" << std::endl;

   std::cout << s[0].string << std::endl;
   //////std::cout << s[1].string << std::endl;

   /*
   char str1[] = "foo";
   strcpy(s[0].string, str1);
   s[0].len = 3;

   char str2[] = "foobar";
   strcpy(s[1].string, str2);
   s[1].len = 6;
   */

   //std::cout << s[0].string << std::endl;
   //std::cout << s[1].string << std::endl;

   std::cout << "Getting out of dll" << std::endl;

   return 1;
}

#endif

и вот простая программа на C #, которую я использую для проверки моей тестовой DLL:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Runtime.InteropServices;

 namespace TestStr
 {
     class Program
     {
         [DllImport("TestStrLib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
         public static extern int TestFunction(string[] s);

         static void Main(string[] args)
         {
             string[] test = new string[2] { "a1a1a1a1a1", "b2b2b2b2b2" };

             Console.WriteLine(test[0]);
             Console.WriteLine(test[1]);

             TestFunction(test);

             Console.WriteLine(test[0]);
             Console.WriteLine(test[1]);

             Console.ReadLine();
         }
     }
 }

И вот результат:

a1a1a1a1a1
b2b2b2b2b2
Just got in dll
b2b2b2b2b2
Getting out of dll
a1a1a1a1a1
b2b2b2b2b2

У меня есть несколько вопросов:

1) Почему он выводит элемент во вторую позицию массива, а не в первую позицию ??

2) Если я раскомментирую строку с комментарием ////// в файле dll, программа вылетает. Почему?

3) Очевидно, я хотел сделать больше вещей в dll (части в / * * /), чем то, что он делает сейчас, но я заблокирован первыми двумя вопросами ...

Спасибо за вашу помощь

1 Ответ

1 голос
/ 16 ноября 2011

Вы не можете маршалировать строку [] как собственную struct

    [DllImport("TestStrLib.dll", CharSet = CharSet.Ansi, 
             CallingConvention = CallingConvention.StdCall)]
             public static extern int TestFunction(string[] s);

      struct strStruct
        {
            int len;
            char* string;
        }

    __declspec (dllexport) int __stdcall TestFunction(strStruct* s);

Пожалуйста, прочитайте http://msdn.microsoft.com/en-us/library/fzhhdwae.aspx для сортировки различных типов.

In C #

    [DllImport( "TestStrLib.dll" )]
    public static extern int TestFunction([In, Out] string[] stringArray
    , int size);

В С ++

__declspec(dllexport) int TestFunction( char* ppStrArray[], int size)
   {
       return 0;
   }
...