为什么NDK在构建时抛出未定义的引用错误?

时间:2021-06-08 05:34:18

I've got this error while I'm trying to build an library with ndk:

我在尝试用ndk建立一个库时犯了这个错误:

$ /cygdrive/d/android-ndk-r10d/ndk-build.cmd [armeabi] SharedLibrary : libgame.so

美元/ cygdrive / d / android-ndk-r10d / ndk-build。共享库:libgame

jni/core/src/coreApplication.cpp:9: error: undefined reference to 'CCoreMessaging::CCoreMessaging()'

jni / / src / coreApplication核心。错误:对“CCoreMessaging:::CCoreMessaging()”的未定义引用

jni/core/src/coreApplication.cpp:11: error: undefined reference to 'CCoreScreenContainer::CCoreScreenContainer()'

jni / / src / coreApplication核心。错误:对“CCoreScreenContainer::CCoreScreenContainer()”的未定义引用

jni/core/src/coreReference.h:75: error: undefined reference to 'CCoreRefClass::_RemoveRef(void*, bool)'

jni / / src / coreReference核心。h:75:错误:对“CCoreRefClass::_RemoveRef(void*, bool)”的未定义引用

jni/core/src/coreReference.h:76: error: undefined reference to 'CCoreRefClass::_AddRef(void*, bool)'

jni / / src / coreReference核心。h:76:错误:对“CCoreRefClass::_AddRef(void*, bool)”的未定义引用

jni/core/src/coreReference.h:58: error: undefined reference to 'CCoreRefClass::_RemoveRef(void*, bool)'

jni / / src / coreReference核心。h:58:错误:对“CCoreRefClass::_RemoveRef(void*, bool)”的未定义引用

jni/core/src/coreReference.h:58: error: undefined reference to 'CCoreRefClass::_RemoveRef(void*, bool)'

jni / / src / coreReference核心。h:58:错误:对“CCoreRefClass::_RemoveRef(void*, bool)”的未定义引用

jni/core/src/coreApplication.h:12: error: undefined reference to 'CCoreMessaging::~CCoreMessaging()'

jni / / src / coreApplication核心。h:12: error:无定义引用“CCoreMessaging::~CCoreMessaging()”

jni/core/src/coreReference.h:58: error: undefined reference to CCoreRefClass::_RemoveRef(void*, bool)'

jni / / src / coreReference核心。h:58:错误:对CCoreRefClass的未定义引用:::_RemoveRef(void*, bool)'

collect2.exe: error: ld returned 1 exit status

collect2。错误:ld返回1退出状态

make.exe: *** [obj/local/armeabi/libgame.so] Error 1

制作。exe:* * *(obj /地方/ armeabi / libgame。所以]错误1

coreApplication.h:

coreApplication.h:

<other includes>
#include "coreResources.h"
#include "coreMessaging.h"

class CCoreApplication
{
public:
CCoreApplication(CCoreContext& a_context);
virtual ~CCoreApplication() {} 

CCoreScreenContainer& GetScreenContainer() { return *m_screenContainer; }
CCoreMessaging& GetMessages() { return m_messages; }

<other functions and properties>
CCoreMessaging m_messages;
};

coreApplication.cpp

coreApplication.cpp

#include "coreApplication.h"
#include "coreMessaging.h"
#include "coreScreenContainer.h"
<other includes>

CCoreApplication::CCoreApplication(CCoreContext& a_context):
 m_context(a_context)
{
m_screenContainer = new CCoreScreenContainer;
GetScreenContainer().SetBounds(CRectangle(0,0, a_context.GetPlatformHandler()->GetResolutionWidth(), a_context.GetPlatformHandler()->GetResolutionHeight()));
}

coreMessaging.h:

coreMessaging.h:

class CCoreMessaging
{
public:
CCoreMessaging(); 
~CCoreMessaging();
void SendMessage(int a_messageID, void* argument0=0, void* argument1=0);
void AddMessageHandler(CCoreMessageHandle& handle, CCoreMessageDelegate handler);
void RemoveMessageHandler(CCoreMessageHandle& handle);
protected:
typedef std::map<int, CCoreMessageDelegate> Map;
Map m_Delegates;
int m_AutoIncrement;
int m_SelfID;
static int m_SelfIDIncrement;
};

coreMessaging.cpp

coreMessaging.cpp

#include "coreMessaging.h"
<other functions>

CCoreMessaging::CCoreMessaging() : m_AutoIncrement(1)
{
m_SelfID = m_SelfIDIncrement++;
gMessaging[m_SelfID] = this;
if(m_SelfID > 127)
    throw std::runtime_error("too many messaging instances");
}

coreReference.h

coreReference.h

class MFAPI CCoreRefClass
{
public:
virtual void Delete() { delete this; }

void _AddRef(void* cls, bool strong);
void _RemoveRef(void* cls, bool strong);

void _IncRef();
bool _DecRef(); // returns true if reference decrease has lead to destruction. false if object is still valid
protected:
CCoreRefClass();
virtual ~CCoreRefClass();

typedef CCoreRefPtr<CCoreRefClass,false> RefType;
std::vector<RefType*> m_refData;

int m_refCount;
};

coreReference.cpp

coreReference.cpp

#include "coreReference.h"

<other functions>
void CCoreRefClass::_RemoveRef( void* cls, bool strong )
{
RefType* refCls = (RefType*)cls;
int lastIdx=(int)m_refData.size()-1;
int refIdx = refCls->m_arrayIndex;
refCls->m_arrayIndex = -1;

// swap erase reference
m_refData[refIdx] = m_refData[lastIdx];
m_refData[refIdx]->m_arrayIndex = refIdx;
m_refData.pop_back();

if(strong)
    _DecRef();
}

void CCoreRefClass::_AddRef( void* cls, bool strong )
{
if(strong)
    _IncRef();

RefType* refCls = (RefType*)cls;
m_refData.push_back(refCls);
refCls->m_arrayIndex = (int)m_refData.size()-1;
}

Most of these errors seem to be produced by a typo, but this code does compile in visual studio as lib completely. I hope it's just something I missed or haven't seen. Feel free to ask for more if needed.

这些错误中的大多数似乎是由拼写错误产生的,但是这些代码在visual studio中作为lib完全编译。我希望这只是我错过或没看到的东西。如果需要的话,可以要求更多。

EDIT: application.mk

编辑:application.mk

APP_STL := gnustl_static
APP_CPPFLAGS += -std=c++11
NDK_TOOLCHAIN_VERSION := 4.8
APP_PLATFORM := android-14

android.mk

android.mk

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)     
# Here we give our module name and source file(s)

LOCAL_MODULE    := game
LOCAL_SRC_FILES := coreBridge.cpp core/game.cpp core/src/coreApplication.cpp
LOCAL_LDLIBS :=  -llog -lGLESv2

include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_EXECUTABLE)

2 个解决方案

#1


2  

thanks to Bogdan V. I found out I needed to include all the source files. But instead of linking them all separately, they're all linkable at once:

多亏了Bogdan v,我发现我需要包含所有的源文件。但它们并不是单独联系它们,它们都是可链接的:

Android.mk:

Android.mk:

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)

# Here we give our module name and source file(s)

LOCAL_MODULE    := libgame
LOCAL_SRC_FILES := coreBridge.cpp core/game.cpp

FILE_LIST := $(wildcard $(LOCAL_PATH)/../../../core/src/*.cpp)
LOCAL_SRC_FILES += $(FILE_LIST:$(LOCAL_PATH)/%=%) LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../core/include

LOCAL_LDLIBS :=  -llog -lGLESv2
LOCAL_CPP_FEATURES += exceptions
LOCAL_SHARED_LIBRARIES := libgame.so

include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_EXECUTABLE)

where :

地点:

FILE_LIST := $(wildcard $(LOCAL_PATH)/../../../core/src/*.cpp)
LOCAL_SRC_FILES += $(FILE_LIST:$(LOCAL_PATH)/%=%) LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../core/include

Is the important part to link them all. This allowed me to create the .so after all.

是把他们全部联系起来的重要部分。这让我创造了。

#2


1  

You didn't add to the build the files that define those symbols:

你没有在构建中添加定义这些符号的文件:

coreMessaging.cpp
coreReference.cpp

presumably

大概

coreScreen.cpp (that i don't see here).

Including the headers means only adding the declarations. You need to compile the sources to get object files that contain the actual symbols that are user at link time.

包含报头意味着只添加声明。您需要编译源代码,以获得包含链接时实际的用户符号的对象文件。

#1


2  

thanks to Bogdan V. I found out I needed to include all the source files. But instead of linking them all separately, they're all linkable at once:

多亏了Bogdan v,我发现我需要包含所有的源文件。但它们并不是单独联系它们,它们都是可链接的:

Android.mk:

Android.mk:

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)

# Here we give our module name and source file(s)

LOCAL_MODULE    := libgame
LOCAL_SRC_FILES := coreBridge.cpp core/game.cpp

FILE_LIST := $(wildcard $(LOCAL_PATH)/../../../core/src/*.cpp)
LOCAL_SRC_FILES += $(FILE_LIST:$(LOCAL_PATH)/%=%) LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../core/include

LOCAL_LDLIBS :=  -llog -lGLESv2
LOCAL_CPP_FEATURES += exceptions
LOCAL_SHARED_LIBRARIES := libgame.so

include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_EXECUTABLE)

where :

地点:

FILE_LIST := $(wildcard $(LOCAL_PATH)/../../../core/src/*.cpp)
LOCAL_SRC_FILES += $(FILE_LIST:$(LOCAL_PATH)/%=%) LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../core/include

Is the important part to link them all. This allowed me to create the .so after all.

是把他们全部联系起来的重要部分。这让我创造了。

#2


1  

You didn't add to the build the files that define those symbols:

你没有在构建中添加定义这些符号的文件:

coreMessaging.cpp
coreReference.cpp

presumably

大概

coreScreen.cpp (that i don't see here).

Including the headers means only adding the declarations. You need to compile the sources to get object files that contain the actual symbols that are user at link time.

包含报头意味着只添加声明。您需要编译源代码,以获得包含链接时实际的用户符号的对象文件。