sourcecode

iPhone ObjectiveC Apps의 C/C++ 정적 라이브러리 사용

codebag 2023. 10. 30. 20:57
반응형

iPhone ObjectiveC Apps의 C/C++ 정적 라이브러리 사용

C++를 내부적으로 사용하고 이것을 라이브러리 사용자에게 숨기는 C static library API를 가질 수 있습니까?

휴대용 C++ 라이브러리를 작성하여 아이폰 애플리케이션에 정적으로 연결하고자 합니다.

Max OS X 'static library' 템플릿을 사용하여 Xcode 프로젝트를 만들고 소스를 가로채 복사했으며 (외부 "C")를 사용하여 (예외 사항을 처리하기 위해) Capper를 작성했습니다.

생성된 라이브러리(.a 파일)를 다른 코코아 아이폰 어플리케이션에서 사용하려고 합니다.

라이브러리의 구현 클래스에서 호출 Objective C 파일에 (.mm) 확장자를 사용하고 구현 클래스에 (.cpp) 확장자를 사용하면 모든 것이 잘 작동합니다.

그러나 래퍼 함수 파일이 모두 C 함수에 불과하지만 래퍼 파일을 (.c) 확장자로 변경하려고 하면 링크 시 해결되지 않은 기호가 나타납니다.

C++가 라이브러리에서 내부적으로 사용된다고 해서 외부적으로는 여전히 C++ 프로그램으로 취급되어야 한다는 것을 의미합니다.이 추상화를 강제할 방법이 없습니까?

편집 : 답변 감사합니다.

저는 외부 "C"를 사용해 왔지만, 호출 프로젝트에서 필요한 구성이 무엇인지 확신할 수 없었습니다.즉, 예측된 호출이 C++를 사용했는지 아니면 무지할 수 있는지 알고 순수하게 C 라이브러리라고 생각해야 하는지를 알아야 하는 경우입니다.

안 될 것 같고, Objective C 클래스에 (.mm) 파일을 사용해야 합니다.

댓글로 이 작업을 하는 것은 너무 어렵기 때문에, 여러분이 겪고 있는 링크 문제가 무엇인지 빠르게 보여드리겠습니다.Xcode는 파일이 발견되면 접미사를 기반으로 빌드 규칙을 사용하여 어떤 컴파일러를 사용할지 결정합니다.기본적으로 gcc는 표준 C 라이브러리에 파일을 연결하지만 표준 C++ 라이브러리에는 연결되지 않습니다.아카이브 파일(정적 라이브러리)에는 연결 확인 작업이 전혀 수행되지 않습니다.기본적으로 연결해야 하는 객체 파일의 아카이브입니다.프로젝트에 .mm 또는 .cpp 파일이 없으므로 g++가 호출되지 않으며 파일이 표준 라이브러리에 연결되지 않습니다.이를 수정하려면 Xcode 프로젝트의 다른 링커 플래그에 표준 C++ 라이브러리를 추가하거나 미리 정의된 다른 플래그 옵션에 -l(예: -lstdc++)로 추가하기만 하면 됩니다.

다음은 간단한 시연입니다.

stw.h:

#ifdef __cplusplus
extern "C"
#endif
void show_the_world(void);

stw.cpp:

#include <iostream>
#include "stw.h"
using namespace std;

extern "C" void show_the_world() {
  cout << "Hello, world!\n";
}

라이브러리를 작성합니다.

$ g++ -c stw.cpp -o stw.cpp -O0 -g
$ ar rcs stw.a stw.o

C 응용프로그램에서 라이브러리 사용하기:

my app.c:

#include "stw.h"

int main() {
  show_the_world();
  return 0;
}

C 애플리케이션 구축:

$ gcc -o myapp myapp.c stw.a -lstdc++ -g -O0
$ ./myapp
Hello, world!
$

-lstdc++ 없이 컴파일을 시도하면 C 컴파일러는 C++ 런타임에 링크해야 한다는 것을 전혀 알지 못하기 때문에 해결되지 않은 모든 문제를 얻을 수 있습니다(그리고 왜 그럴까요?)!따라서 수동으로 추가해야 합니다.프로젝트의 빌드 규칙을 변경하는 방법도 있습니다.Xcode가 .c와 .m 파일을 만들기 위해 gcc를 사용하도록 하는 대신, g++를 사용하라고 하면 문제가 해결될 것입니다.

표시할 기능을 선언해야 합니다.extern "C"의 서명은 C 를 들어 C 직접 할 수는 는 괜찮습니다 이들의 서명은 C 호환이 되어야 하지만 내용은 그렇지 않습니다(예를 들어 C++ 개체에 액세스할 수는 있지만 직접 전달할 수는 없습니다. 포인터는 괜찮습니다.그러면 C 호환 환경에서는 기호를 볼 수 있습니다.

편집: 그리고 C++ 소스 파일로 컴파일해 주세요, C는 언어 연결 개념이 없습니다.언어 연결과 관련된 몇 가지 다른 문제들이 있습니다. (예를 들어 모든 것이extern "C"이름이 같은 함수는 네임스페이스에 관계없이 동일한 함수입니다.

EDIT2: 헤더에서 매크로를 확인할 수 있습니다.__cplusplus, C++와 다른 언어를 각각 설정하는 데 사용합니다(C++는 다음을 요구하기 때문입니다).extern "C"선언, 그리고 다른 언어들은 아마도 그것들에 대해 불평할 것입니다).

기본적으로 C++ 컴파일러로 C 함수를 컴파일하면 함수 이름을 스매싱하고 C++ ABI를 사용합니다.

*.cpp 또는 *.mm 확장자를 사용할 때는 C++ 컴파일러를 사용합니다.

당신이 원하는 것은 컴파일러가 C 함수를 생성하도록 강요하고 CBI를 사용하는 것입니다.

이 작업은 다음 중 하나를 통해 수행할 수 있습니다.

  • C 컴파일러로 컴파일합니다.
  • C++ 컴파일러로 컴파일하되 함수 선언 앞에 외부 "C"를 붙여야 합니다.

C 및 C++ 소스 파일 모두에서 동일한 파일을 포함할 수 있도록 헤더 파일을 설정하는 가장 선호되는 방법은 다음과 같습니다.

#ifndef HEADER_GUARD_1_H
#define HEADER_GUARD_1_H

#ifdef __cplusplus
extern "C" {
#endif

// Declare C function interface here.
int myFunc(int x,char*);

#ifdef __cplusplus
}
#endif

#endif 

이렇게 좋은 토론을 해주셔서 감사합니다.

제가 한 일은:

1) 저는 코카터치 스태틱 립 옵션을 사용하여 스태틱 립을 만들었습니다.그래서 c/c++/obj-call mix가 있습니다.하지만 저의 수출품은 obj-c 클래스 뿐입니다.사실 저는 c++에 objc- to c를 사용했습니다.

2) X-code proj에서 아이폰 앱을 만들었습니다.다른 링크 플래그를 추가했습니다. 내 lib 이름(-lxyz) //내 lib 이름은 libxyz입니다.lib 검색 경로, 헤더 검색 경로를 추가했습니다.

3) 그 다음에 정리를 했습니다.오류가 발생했습니다. 새로운 운영자 삭제를 찾을 수 없습니다.

3) 그런 다음 앱 딜러, 뷰 컨트롤러를 분리하고 더미 cpp(.h, .cpp)를 추가했습니다.테스트 더미.혐오 테스트 더미

4) 그리고 난 다시 짓습니다...

효과가 있었단 거지

그래서 - 나는 그들이 이전에 어떤 제안을 했든 간에 나에게 효과가 있었습니다. 기본적인 이유는 앱에서 cpp 코드가 있는 .cpp 파일 .mm 파일을 보지 않는 한 링크된 g++를 사용하지 않을 것입니다.

다들 감사합니다.위의 내용을 읽고 문제를 해결했습니다.

여러분들은 나눠먹기 좋아요.

언급URL : https://stackoverflow.com/questions/376966/using-c-c-static-libraries-from-iphone-objectivec-apps

반응형