p / вызвать вызов C dll из c # - PullRequest
       25

p / вызвать вызов C dll из c #

0 голосов
/ 17 января 2012

это мой код C

extern "C"
{ 
     __declspec(dllexport) void DisplayHelloFromDLL(string a)
   {    
     printf ("%s\n",a)
   }
}

это мой код C #

class HelloWorld
{
    [DllImport("TestLib.dll")]
    public static extern void DisplayHelloFromDLL(string a);

    static void Main ()
    {
        string a = "Hello";
        DisplayHelloFromDLL(a);
    }
}

Он успешно построен, но вылетает так:

Отладка http://i44.tinypic.com/1qr9sj.jpg

Итак, как использовать P / invoke для вызова моей собственной библиотеки Cll из C #? Пожалуйста, помогите, спасибо заранее.

Ответы [ 4 ]

2 голосов
/ 17 января 2012

Прежде всего, ваш код - C ++, а не C. Ваша функция получает параметр типа std::string, а использование std::string означает, что ваш код на самом деле C ++.

Теперь этот тип параметракорень вашей проблемы.Вы не можете создать std::string в .net, и вместо этого вам нужно будет использовать char* для передачи строковых данных.Вам нужен следующий код:

C ++

__declspec(dllexport) void DisplayHelloFromDLL(char* a)
{    
    printf("%s\n", a);
}

C #

[DllImport("TestLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void DisplayHelloFromDLL(string a);

static void Main ()
{
    string a = "Hello";
    DisplayHelloFromDLL(a);
}

По умолчанию p /вызвать маршаллинг для .net string - передать char* в качестве параметра [In].Нет необходимости в сложности IntPtr, StringToHGlobalAnsi, FreeHGlobal, как предполагает один из других ответов.Если вы можете позволить маршаллеру p / invoke выполнять эту работу, то лучше сделать это.

Обратите внимание, что вам также необходимо убедиться, что ваши соглашения о вызовах совпадают.При условии, что вы не использовали никаких специальных опций компилятора при создании кода C ++, этот код по умолчанию будет использовать cdecl соглашение о вызовах.Вы можете сопоставить это с параметром CallingConvention с атрибутом DllImport.

2 голосов
/ 17 января 2012

Пожалуйста, посмотрите на строку сортировки в MSDN

В скорлупе ореха строка C # не маршалируется как std::string, а char* по умолчанию

1 голос
/ 17 января 2012

Измените тип вашего параметра C ++ на char * и обновите ваш код C # следующим образом

class HelloWorld
{
  [DllImport("TestLib.dll")]
  public static extern void DisplayHelloFromDLL(IntPtr a);

  static void Main ()
  {
    string a = "Hello";
    var ptr = System.Runtime.Marshal.StringToHGlobalAnsi(a);
    DisplayHelloFromDLL(ptr);
    System.Runtime.Marshal.FreeHGlobal(ptr);
  }
}
1 голос
/ 17 января 2012

С одной стороны, возвращаемый тип не совпадает.В C это void и в C # int.

...