Я знаю, что есть много вопросов, связанных с этим, но ни один из тех, с которыми я столкнулся, не решает мою проблему. Так вот.
У меня есть файл и метод C++
:
MyClass.cpp
extern "C" {
#include "C_methods.h"
}
void MyClass::run_c_method_1()
{
std::string filename_1 = <from somewhere else>;
std::string filename_2 = <from somewhere else>;
c_method_1(filename_1.c_str(), filename_2.c_str());
}
C_methods.h
#ifndef Project_C_methods_h
#define Project_C_methods_h
int c_method_1(char* filename1, char* filename_2);
#endif
C_methods.c
#include "C_methods.h"
int c_method_1(char* filename1, char* filename_2) {
/* Do some stuff */
return 0;
}
Я создаю/запускаю это на OSX
в Xcode
, и компилятор говорит мне:
No matching function call to 'c_method_1'
.
Для меня это бессмысленно. Из других ответов SO, похоже, что extern
который я завернул в заголовок #include "C_methods.h"
должен сообщить компилятору, что эти функции присутствуют, и скомпилироваться на C
Кто-нибудь знает, где я могу ошибиться? Я в тупике.
На самом деле ваша проблема может быть упрощена:
#include <string>
void foo(char *);
int main() {
std::string s;
foo(s.c_str());
}
Функция принимает char *
, но ему передается const char *
. Если функция не изменяет pointee, она должна принимать const char *
. В противном случае вам придется использовать модифицируемый буфер. Начиная с С++ 11, std::string
&s[0]
подсчитывается как один до момента, пока не будет указан нулевой символ в конце. До этого вам лучше с std::vector<char>
.
Если унаследованная функция принимает указатель не const, но вы знаете, что он НЕ будет изменять данные (общие в старом C-коде), тогда допустимо использовать в этом случае const_cast<char *>(s.c_str())
, Если функция изменяет данные, это неопределенное поведение!
Если функция может изменить данные, вам необходимо скопировать строку в модифицируемый буфер и передать вместо этого указатель.
string s;
vector<char> buffer(s.size() + 1); // prepare buffer, with space for null char
strcpy(buffer.data(), s.c_str()); // copy string data
foo(buffer.data());
s = buffer.data(); // copy back string data if required
extern "C"
и использовать __BEGIN_DECLS / __ END_DECLSchar *
не является постояннымconst char *
. Было бы легче заметить, если бы была опубликована полная ошибка.