Экспорт искаженных функций cpp из сторонней библиотеки - PullRequest
0 голосов
/ 10 июля 2019

У меня есть сторонняя библиотека в качестве исходного кода. Он поставляется с проектом Visual Studio, который создает из него .lib.

Я хочу получить доступ к функциональности из C #, поэтому я скопировал проект и изменил его, чтобы создать DLL.

DLL не содержала экспортируемых функций, поэтому я также создал файл определения модуля (.def) и добавил нужные мне функции в разделе EXPORTS.

Это работает для всех функций, которые объявлены в extern "C" блоках. Однако некоторые функции, которые мне нужны, объявлены вне этих блоков.

Если я добавлю их в раздел ЭКСПОРТ, я получу ошибку LNK2001 unresolved external symbol XYZ: (

Я не хочу менять исходный код сторонней библиотеки, если я могу этого избежать.

Какой самый элегантный и, надеюсь, самый простой способ получить доступ к этим функциям?

Редактировать

Еще одно уточнение: насколько я могу судить, в интерфейсе, который я хочу раскрыть, не задействованы функции C ++. Честно говоря, я не понимаю, почему сторонние авторы не просто включили несколько оставшихся функций в блоки extern "C". Эти функции находятся внизу файла заголовка, возможно, тот, кто их добавил, просто допустил ошибку и вывел их за пределы extern "C" блоков.

1 Ответ

2 голосов
/ 10 июля 2019

Для C ++ одним из способов (ИМХО самый элегантный) было бы использование C ++ / CLI, который предназначен для этого. Особенно, если у вас есть не только функции, но и классы.

Вы создаете тонкий слой-обертку, который довольно прост:

  1. Создать класс CLI
  2. положить экземпляр члена исходного класса
  3. Обернуть все открытые методы из исходного класса

Как это (не проверено):

C ++ натив:

// original c++ class
class Foo {
public:
    Foo(int v) : m_value(v) {}
    ~Foo() {}

    int  value()      { return m_value; }
    void value(int v) { m_value = v; }

private:
    int m_value;
};

Оболочка CLI:

// C++/CLI wrapper
ref class FooWrap
{
public:
    FooWrap(int v) { m_instance = new Foo(v); }
    !FooWrap()     { delete m_instance; }
    ~FooWrap()     { this->!FooWrap(); }

    property int value {
        int  get()      { return m_instance->value(); }
        void set(int v) { m_instance->value(v); }
    }

private:
    Foo *m_instance;
};

Здесь вы можете найти краткое руководство, которое описывает его более подробно.

Edit:

Из ваших комментариев:

[...] Я никогда не работал с C ++ / CLI, и язык выглядит немного запутанным. Поскольку крайний срок проекта довольно близок, я не уверен, достаточно ли времени для его изучения. Я обязательно запомню этот вариант!

Если вы не ищете самый элегантный способ, как в исходном вопросе, но самый быстрый / кратчайший путь: для C ++ один способ (ИМХО самый короткий путь) будет использовать C ++ / CLI , который предназначен для этого. Особенно, если у вас есть не только функции, но и классы. Вы создаете тонкий слой-обертку, который довольно прост ... Здесь вы можете найти короткое (за 10 минут) руководство, которое описывает его более подробно.

...