передача указателей с C на C ++ и наоборот - PullRequest
5 голосов
/ 16 января 2010

Есть ли какие-нибудь советы, которые можно дать мне о передаче указателей на структуры, дубликаты, функции ... из программы на C в библиотеку C ++ и обратно?

Ответы [ 3 ]

10 голосов
/ 16 января 2010

Предполагается, что вы кодируете их в двух разных библиотеках - статической или динамической (библиотеки DLL в общих библиотеках Windows в Linux и других * nix-вариантах). Самая большая проблема, с которой я сталкиваюсь, заключается в следующем:

  1. Они компилируются одним и тем же компилятором. Хотя в этом нет необходимости, если все экспорты C ++ экспортируются с соглашением об именах в стиле C, для вызовов C ++ к C ++ необходимо создавать экземпляры классов между двумя модулями C ++. Это необходимо из-за того, что разные компиляторы по-разному управляют экспортом в C ++.

  2. Не приводите класс C ++ как структуру C. Они не одинаковы под обложками, даже если расположение полей одинаково. Классы C ++ имеют "v-таблицу", если у них есть виртуальные члены; эта таблица позволяет правильно вызывать методы унаследованного или базового класса.

  3. Это верно для C на C или C ++ на C ++, а также C на C ++. Убедитесь, что оба используют одинаковое байтовое выравнивание для выходной библиотеки. Вы можете определить это, только прочитав документацию по компилятору или среде разработки.

  4. Не смешивайте malloc / free с новым / delete. В частности, не выделяйте память с новой и свободной памяти с «свободным» и наоборот. Многие компиляторы и операционные системы по-разному управляют памятью.

  5. Передача указателей на функции: до тех пор, пока они выставляются в / из C ++ как '' extern "C" '', это должно быть хорошо. (Вам нужно будет либо обратиться к документации по компиляторам о том, как определить, когда заголовок компилируется как C или C ++, чтобы сохранить это в одном файле, либо вам потребуются две отдельные копии одного и того же объявления функции в каждом проекте - я рекомендую первое)

  6. Передача double: это встроенный тип в C и C ++, и он должен обрабатываться одинаково.

  7. Если вам нужно совместно использовать экземпляр объекта C ++ с функцией C и действовать в нем из кода C, предоставьте набор экспортированных из C вспомогательных функций, которые вызывают соответствующие методы объекта C ++. Чистый код C не может правильно вызывать методы для объектов C ++.


    Pseudocode-ish Example:
    // C++ class
    class foo {
       public:
           void DoIt();
    };

    // export helper declarations
    extern "C" void call_doit(foo* pFoo);
    extern "C" foo* allocate_foo();
    extern "C" deallocate_foo(foo* pFoo);


    // implementation
    void call_doit(foo* pFoo)
    {
        pFoo->DoIt();
    }

    foo* allocate_foo()
    {
        return new foo();
    }

    deallocate_foo(foo* pFoo)
    {
       delete pFoo;
    }

    // c consumer
    void main()
    {
        foo* pFoo= allocate_foo();
        call_doit(pFoo);
        dealocate_foo(pFoo);
    }


0 голосов
/ 16 января 2010
  • не забудьте ключевое слово extern "C" , чтобы избежать проблем с каландрированием C ++ имя.
  • Не использовать передачу по ссылочному типу аргумента, но указатель
0 голосов
/ 16 января 2010

C и C ++ указатели одинаковы - указатель в основном указывает на блок памяти, и это не меняется по сравнению с C / C ++.

Вы хотите быть осторожными, чтобы не пересекать типы кучи - например, не размещать в одной библиотеке и не перераспределять в библиотеке, которая может иметь другую кучу или использовать другую версию времени выполнения (или наоборот).

Вы хотели задать вопрос о передаче по значению или передаче по ссылке? Это может помочь дать более конкретный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...