Вызов C++ статические функции членства из кода C

У меня есть набор кода C. У меня нет намерения преобразовать их в код C++.

Теперь, я хотел бы назвать некоторый код C++ (я не возражаю для изменения кода C++ так, чтобы они были вызываемыми кодом C).

class Utils {
public:
    static void fun();
}

class Utils2 {
public:
    static std::wstring fun();
}

Если я склонен называть их со следующим синтаксисом, они привычка скомпилированный (я использую VC ++ 2008 с файлами кода C с.c расширением),

Utils::fun();
// Opps. How I can access std::wstring in C?
Utils2::fun();

Какое-либо предложение?

7
задан Cheok Yan Cheng 7 July 2010 в 08:19
поделиться

11 ответов

// c_header.h
#if defined(__cplusplus)
extern "C" {
#endif

void Utils_func();
size_t Utils2_func(wchar_t* data, size_t size);

#if defined(__cplusplus)
}
#endif
//eof

// c_impl.cpp
// Beware, brain-compiled code ahead!
void Utils_func()
{
  Utils::func();
}

size_t Utils2_func(wchar_t* data, size_t size)
{
  std::wstring wstr = Utsls2::func();
  if( wstr.size() >= size ) return wstr.size();
  std::copy( wstr.begin(), wstr.end(), data );
  data[wstr.size()] = 0;
  return str.size();
}
//eof
8
ответ дан 6 December 2019 в 15:18
поделиться

Как насчет оболочки

extern "C" void Utilsfun(int i){Utils::fun(i);}

Обновление:

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

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

extern "C"
{
void * ObjectCreate(){return (void *) new Object();}
void ObjectOperate(void *object, char *parameter){((Object*)object)->Operate(parameter);}
void ObjectDelete(void *object){delete ((Object*)object);}
}

Вы должны быть очень осторожны с управлением созданием и удалением.

6
ответ дан 6 December 2019 в 15:18
поделиться

Наиболее распространенное решение - написать интерфейс C для ваших функций C ++. Это код C ++, объявленный с использованием extern «C» {...} . Эти функции-оболочки могут свободно вызывать любой код C ++, который им нравится, но поскольку они объявлены extern «C» , они не будут подвергаться изменению имен (здесь нельзя выполнять пространства имен или перегрузку) .

Это должно быть связано с вашим файлом C, и все готово.

То есть заголовочный файл содержит

#ifdef __cplusplus
extern "C" {
#endif

  void wrapper1(void);
  int wrapper2(int x);
  char* wrapper3(int y);

#ifdef __cplusplus
}
#endif

ifdefs, необходимые для защиты компилятора C от внешнего "C" . И вы реализуете их в своем исходном коде C ++

void wrapper1(void) { Util::funcOne(); }
int wrapper2(int x) { return Util::funcTwo(x); }
char* wrapper3(int y) { return Util::funcThree(y); }
1
ответ дан 6 December 2019 в 15:18
поделиться

Создайте функцию-оболочку в коде C ++:

extern "C" void Wrapper() {
    Utils2::fun();
}

, а затем в коде C:

extern void Wrapper();
int main() {
    Wrapper();
    return 0;
}
1
ответ дан 6 December 2019 в 15:18
поделиться

Я думаю, что единственное решение состоит в том, чтобы обернуть их в глобальные функции в стиле C в коде C++, например:

extern "C" int Util2_Fun() { return Util2::Fun(); }

Я полагаю, что вы также можете объявить глобальные указатели функций как экстерны, используя некоторые неприятные вариации:

extern int (*Utils2_Fun)()=(int *())(Util2::Fun);

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

1
ответ дан 6 December 2019 в 15:18
поделиться

Если вы сделаете так, как написано здесь (используя extern "C"), остерегайтесь того, что вы передаете в функцию C только те объекты, которые компилируются в C.

.
0
ответ дан 6 December 2019 в 15:18
поделиться

Вы можете сделать C ++ вызываемым из C с помощью конструкции extern «C» .

0
ответ дан 6 December 2019 в 15:18
поделиться

Если у вас есть контроль над всеми исходными текстами, я бы не стал пытаться сохранить их часть в формате С. Они должны компилироваться как C++ (или легко изменяться, чтобы сделать это). Это не значит, что вам нужно переписать его как C++, просто скомпилируйте его как таковой. Таким образом, вы сможете использовать любые части C++, которые имеют смысл. Со временем код на Си станет более похожим на C++, но это будет происходить медленно, по мере возникновения необходимости.

Конечно, если вам нужно, чтобы он оставался компилируемым на Си по другим причинам, это не применимо.

0
ответ дан 6 December 2019 в 15:18
поделиться

У вас не будет никакого практического использования объектов c++ в вашем коде C, поэтому вы, вероятно, захотите создать что-то вроде "C Binding" для вашего кода C++, который состоит из некоторого количества обычных функций, вызываемых из C, и возвращающих только обычные типы данных C. Ваши функции-обертки могут затем вызывать всевозможные классы, объекты и т.д. Но они предоставляют более простой интерфейс в стиле C для объектов, которые вы можете использовать из C для преодоления разрыва. Вы также можете использовать указатели функций в некоторых случаях, чтобы дать доступ к статическим методам в Си, но обычно проще просто создать обертку, ИМХО.

0
ответ дан 6 December 2019 в 15:18
поделиться

C является подмножеством C++ ... Поэтому вы не можете называть члены класса и пространства имен в Си++.

-3
ответ дан 6 December 2019 в 15:18
поделиться

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

0
ответ дан 6 December 2019 в 15:18
поделиться