Как создать DLL в C ++ для использования в C # - PullRequest
8 голосов
/ 03 декабря 2011

У меня небольшой вопрос к вам.

У меня есть один исходный код C ++ и один заголовочный файл.Файл C ++ использует библиотеку windows.h, выполняет операции с использованием последовательного порта (основные операции: read (), write () и т. Д.).

Я хочу создатьиспользовать эти файлы и использовать эту библиотеку в моем C # .Net решении .

Какой тип библиотеки мне нужно создать?Как мне это сделать?После создания библиотеки, как я могу импортировать ее в решение C #?

Мои наилучшие пожелания.

Части кода, которые я использую:

// MathFuncsDll.h

namespace MathFuncs
{
    class MyMathFuncs
    {
    public:
        // Returns a + b
        static __declspec(dllexport) double Add(double a, double b);

        // Returns a - b
        static __declspec(dllexport) double Subtract(double a, double b);

        // Returns a * b
        static __declspec(dllexport) double Multiply(double a, double b);

        // Returns a / b
        // Throws DivideByZeroException if b is 0
        static __declspec(dllexport) double Divide(double a, double b);
    };
}

// MathFuncsDll.cpp
// compile with: /EHsc /LD

#include "MathFuncsDll.h"

#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    double MyMathFuncs::Add(double a, double b)
    {
        return a + b;
    }

    double MyMathFuncs::Subtract(double a, double b)
    {
        return a - b;
    }

    double MyMathFuncs::Multiply(double a, double b)
    {
        return a * b;
    }

    double MyMathFuncs::Divide(double a, double b)
    {
        if (b == 0)
        {
            throw new invalid_argument("b cannot be zero!");
        }

        return a / b;
    }
}

C # импортная часть:

[DllImport("SimpleDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern double Add(double a, double b);

static void Main(string[] args)
{
    string a = Add(1.0, 3.0));
}

Ответы [ 4 ]

7 голосов
/ 03 декабря 2011

После нескольких комментариев, вот попытка:

Код C ++ (DLL), например.math.cpp, скомпилированный в HighSpeedMath.dll:

extern "C"
{
    __declspec(dllexport) int __stdcall math_add(int a, int b)
    {
        return a + b;
    }
}

C # код, например.Program.cs:

namespace HighSpeedMathTest
{
    using System.Runtime.InteropServices;

    class Program
    {
        [DllImport("HighSpeedMath.dll", EntryPoint="math_add", CallingConvention=CallingConvention.StdCall)]
        static extern int Add(int a, int b);

        static void Main(string[] args)
        {
            int result = Add(27, 28);
        }
    }
}

Конечно, если точка входа уже совпадает, указывать ее не нужно.То же самое с соглашением о вызовах.

Как уже упоминалось в комментариях, DLL должна предоставлять C-интерфейс.Это означает, что extern "C", без исключений, без ссылок и т. Д.

Edit:

Если у вас есть заголовок и исходный файл для вашей DLL, он можетвыглядеть так:

math.hpp

#ifndef MATH_HPP
#define MATH_HPP

extern "C"
{
    __declspec(dllexport) int __stdcall math_add(int a, int b);
}

#endif

math.cpp

#include "math.hpp"

int __stdcall math_add(int a, int b)
{
    return a + b;
}
5 голосов
/ 03 декабря 2011

Вам необходимо скомпилировать ваш код C ++ в библиотеку динамических ссылок и сделать следующее в C #:

  class MyClass
  {
  [DllImport("MyDLL.dll")]
  public static extern void MyFunctionFromDll();

        static void Main()
        {
              MyFunctionFromDll();
        }
  }
1 голос
/ 03 декабря 2011

Вы можете использовать C # DllImport и Dllexport для DLL Interop пошаговое руководство в качестве отправной точки.А вот Учебник по платформе

Надеюсь, это поможет.

1 голос
/ 03 декабря 2011

В дополнение к предложению Личиана скомпилировать в обычную DLL и использовать p / invoke, что, вероятно, является самым простым способом Вы также можете создать свой C ++ как компонент COM (вероятно, то, что вы не хотите делать), и третий вариант, который у вас есть, - добавить тонкий слой C ++ / CLI. например,

using namespace System;

namespace youcomany{ namespace CPPWrapper
{
    Wrapper::Function(String^ parameter)
    {
        //call the rest of you C++ from here
        }
}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...