문제

VC ++의 컴파일러로 래퍼 라이브러리를 구축하려고합니다.

erldriver.c

#define __WIN32__
#define DLL_EXPORT __declspec(dllexport)

#include "erl_driver.h"

DLL_EXPORT int _driver_output(ErlDrvPort port, char *buf, int len) {
    return driver_output(port, buf, len);
}

build.bat

cl /I%ERL_DRIVER_H% /LD /MD ErlDriver.c

이것을 만들려고하면 다음 링커 오류가 발생합니다.

erldriver.obj : Error LNK2019 : 미해결 외부 기호 _windyndrivercallbacks function __driver_output

ERL_WIN_DYN_DRIVER.H (포함 된 ERL_DRIVER.H)

typedef struct {
    WDD_FTYPE(driver_output) *driver_output;
    // a ton more of those
} TWinDynDriverCallbacks;

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

#define driver_output (WinDynDriverCallbacks.driver_output)

보시다시피 WindyndriverCallbacks는 다음과 같습니다 한정된 선언.

그렇다면 링커 오류를 일으킬 수있는 것은 무엇입니까?

도움이 되었습니까?

해결책

C 또는 C ++에서 "선언"과 "정의"사이에는 미묘한 차이가 있습니다. 당신이 그것을 선언 할 때, 그것은 컴파일러에 특정 기호가 다른 곳에서 정의 될 것이라고 알려줍니다. 이것은 실제 정의를 볼 필요없이 코드가 해당 기호를 사용할 수 있습니다. 링크 된 코드 어딘가에있는 기호를 여전히 정의해야합니다. 그렇지 않으면보고있는 오류 메시지가 표시됩니다.

예를 들어, 이것은 기호의 선언입니다. WinDynDriverCallbacks:

extern TWinDynDriverCallbacks WinDynDriverCallbacks;

코드에는이 선언이 있습니다. 기호를 사용하는 코드가 성공적으로 컴파일되지만 링크는 아닙니다.

어딘가에 정의를 추가해야합니다.

TWinDynDriverCallbacks WinDynDriverCallbacks;

정의는 어딘가에 소스 코드 파일로 이동해야합니다 (일반적으로 헤더 파일이 아님). 이를 통해 컴파일러는 해당 객체의 객체 코드에 공간을 할당하도록 지시하고 프로그램이 성공적으로 연결되도록합니다.

다른 팁

아니요, 그것은 정의되지 않았습니다 (적어도 당신이 인용 한 것). 선언되었습니다. "extern 키워드"는 "이 기호의 정의는 다른 컴파일 장치 (소스 파일)에 나타납니다." 해당 기호를 정의하는 소스 파일을 컴파일하여 생성 된 개체 파일 (또는 라이브러리)과 연결해야합니다.

Windows에서 NIF를 구축하는 매우 비슷한 문제가 있습니다. 해결되지 않은 외부 기호 _windynnifcallbacks. 이것은 ERL_NIF_INIT 매크로에 의해 정의되며, 제 경우에는 전체 매크로가 외부 C 블록에 포함되어야했습니다.

즉, 이것은 실패했습니다

extern "C" ERL_NIF_INIT(...)

이것이 성공하는 동안

extern "C"
{
   ERL_NIF_INIT(...)
}

이 문제는 동일한 문제로 인한 것으로 의심하지만 Erlang 포트 드라이버의 경우 Driver_init 매크로와 관련이 있습니다.

Driver_init은 "TwindyndriverCallbacks WindyndriverCallbacks"를 선언하는 기본 루프입니다. 그러나 Driver_Init에 대한 여러 줄 정의에서 올바르게 선언됩니다. extern "c"로 랩핑 할 필요가 없습니다.

이 스레드가 내 베어 본 Erlang 포트 드라이버를 설정하려고하는 동안 약 백만 번 등장했기 때문에 여기에서 말할 것입니다. Joe Armstrong의 프로그래밍 Erlang 책인 12 장 인터페이스 기술에서 일하고 있습니다. ERL5.9 및 VS2010 사용.

이 책의 코드는 example1_lib.c에서 누락과 오류가있었습니다. 오류는 책의 나이와 Erlang 버전이 변경 되었기 때문일 가능성이 높습니다.

설정해야합니다 (#define Win32) example1_lib.c의 최상위에서 Erlang은 모든 Linux 옵션에 기본적으로 기본값을 받았습니다.

두 번째는 example_drv_output에서 (int bufflen)으로 (erldrvsizet bufflen)으로 변경해야했습니다.

그 후 그것은 깨끗하게 만들었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top