Member 10854414 Ответов: 5

C# неуправляемый экспорт / импорт DLL в C++


0 голосовать против фаворита


У меня есть следующий код в C#: (я использовал шаблон R. Giesecke Dllexport для создания неуправляемой библиотеки Dll с C#... он создает мне файл ".lib" и ".dll" с (управляемым) C# )
//UnmanagedExports.cs
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;

namespace AddDll
{
   class MyAddDll
   {
      [DllExport("Add", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
      public static double Add(double a, double b)
      {
         return a + b;
      }
   }
}

Dll-код C# работает хорошо без ошибок и создает мне Addll. lib и AddDll.dll файл.

Я хотел бы импортировать эту библиотеку Dll в C++:
//CallAdd.h

#pragma once

#define DllImport __declspec(dllimport) 

namespace AddDll
{
    class MyAddDll
    {
    public:
        static DllImport double Add(double a, double b);
    };
}

// CallAdd.cpp

#include "stdafx.h"
#include"CallAdd.h"
#include <iostream>



using namespace std;

int main()
{
    double a = 4.5;
    double b = 5.5;

    cout << "a + b = " << AddDll::MyAddDll::Add(a, b) << endl;

    system("pause");

    return 0;
}

У меня есть следующие ошибки:

Warning 1 Platform is AnyCpu, creating binaries for each CPU platform in a separate subfolder...<br />
<br />
    Error 2 error LNK2019: unresolved external symbol "__declspec(dllimport) public: static double __cdecl AddDll::MyAddDll::Add(double,double)" (__imp_?Add@MyAddDll@AddDll@@SANNN@Z) referenced in function _main<br />
<br />
    Error 3 error LNK1120: 1 unresolved externals


В Visual Studio я сделал следующее В разделе свойства консольного приложения C++ :

- В общих свойствах - & gt; рамки и ссылки. Добавьте ссылку на проект Addll.
Свойства - > конфигурация; Компоновщик ‐&ГТ; вход. Дополнительные зависимости Addll.lib
- В свойствах конфигурации - & gt; Компоновщик - & gt; Общие сведения. Дополнительные библиотечные каталоги, добавить
каталог, в котором Addll. lib и AddDll.dll расположены

Может ли кто-нибудь помочь мне устранить эти ошибки?

Заранее спасибо!!

Daniele Rota Nodari

Привет.

Вы решили этот вопрос?

5 Ответов

Рейтинг:
2

Member 10854414

Эй Праввин,
предупреждение исчезло.

Рейтинг:
2

David Knechtges

Вы также можете просто скомпилировать ваш код C# как обычно (.Продажи) код, и компилировать C++ код как C++/CLI для. Что можно использовать оба .Чистый и неуправляемый код в одних и тех же файлах. Если вам нужно разделение между ними .NET и неуправляемый код C++, вы также можете написать DLL-оболочку в C++/CLI для взаимодействия между 2.


Member 10854414

Привет Давид,
спасибо за ваш ответ. Проблема в том, что я не могу найти существующую оболочку для массивов. Для этого мне нужен шаблон...

Рейтинг:
1

Shawn-USA

Привет,

Этому вопросу 2 года, но ответ никогда не бывает старым. Я отвечаю на этот вопрос абсолютно правильным ответом. Другие разработчики могут извлечь выгоду из моего ответа. Он был опубликован три раза, потому что веб-сайт заявил, что он не смог опубликовать его 2 раза по ошибке.

Проблема зависит от того, как вы импортируете функцию в свой собственный код C++. Вы не можете делать то, что делаете сейчас. Если вы используете следующий код C++ для импорта своей функции, имя функции экспорта должно быть искажено, вы должны придумать точное искаженное имя, как это делает Visual C++. Я удалил ссылку на свою статью, хотя статья написана хорошо.

//CallAdd.h

#pragma once

#define DllImport __declspec(dllimport) 

namespace AddDll
{
    class MyAddDll
    {
    public:
        static DllImport double Add(double a, double b);
    };
}


Вместо использования пространства имен и класса вы должны просто использовать оператор extern "C", как показано ниже.

extern "C"
{
    double Add(double a, double b);
}


Поскольку соглашение о вызове по умолчанию в C++ является __cdecl, вам также нужно будет изменить соглашение о вызове в коде C#, помните, что имя __stdcall функции экспорта также должно быть искажено, в этом случае это Add@16, вы не хотите делать искаженное имя, поэтому, пожалуйста, просто используйте __cdecl, это намного проще.

//UnmanagedExports.cs
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
 
namespace AddDll
{
   class MyAddDll
   {
      [DllExport("Add", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
      public static double Add(double a, double b)
      {
         return a + b;
      }
   }
}


Рейтинг:
0

KarstenK

вам нужно построить c#-dll для того же процессора, что и ваш проект C++. : - O


Member 10854414

Спасибо! Предупреждение исчезло. Но ошибки все равно есть :(

Рейтинг:
0

Daniele Rota Nodari

Привет.

Ошибка, о которой вы сообщили, гласит, что компоновщик ищет функцию экспорта с помощью _Слова _cdecl соглашение о вызове, но вы экспортировали из C# как Нарушением соглашения о стандартном.

Пробовали ли вы изменить CallingConvention в своем коде C# или добавить ключевое слово _ _ stdcall в инструкцию импорта C?

Пожалуйста, смотрите Перечисление CallingConvention[^], Ошибка компоновщика lnk2019[^] и _Указывая[^].

С уважением,
Даниеле.