跳至主要內容

F1.模块(项目)名_API

Mr.Si大约 4 分钟u++Specifiers

头像
Baba我真的快疯掉了!
头像
怎么了?
头像
在虚幻引擎中添加一个类,自动生成的代码中经常可以看到形如"模块(项目)名_API"的字样,具体是拿来干什么的?
头像
宏函数(Macro)知道吧,一种预处理器指令,用于在编译之前进行文本替换,UE中这种大写的一般就是宏函数。
头像
为什么要写这么多宏函数呢?
头像
为了简化编码、提高性能、实现特定功能等。
头像
那我们能讲讲一些常用的宏以及用途吗?
头像
一口吃不成胖子,先来了解一下你提到的这个宏:模块(项目)名_API

模块(项目)名_API

头像

模块(项目)名_API 通常用于标记导出和导入规范,特别是在涉及到使用动态链接库(DLL)的情况下。
确保在使用该库的项目中,类和函数的声明和定义能够正确地导入和导出(控制代码对外的可见性)

头像
我不理解!能举个例子吗?
头像
那就拿我们截图的蓝图函数库类为例吧
头像
新建一个蓝图函数库
#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "TEST.generated.h"

UCLASS()
class MYGame_API UTEST : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
	
	UFUNCTION(BlueprintCallable, Category ="TEST")
	static void TestFun();
	
};
头像
去掉EXORCIST_API
#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "TEST.generated.h"

UCLASS()
class UTEST : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
	
	UFUNCTION(BlueprintCallable, Category ="TEST")
	static void TestFun();
	
};
头像
编译后都没问题啊!
头像

别急,重点康康蓝图里去掉MYGame_API还能不能用。

头像
Good!目前来说他不会影响反射到蓝图节点中。
头像

继续测试,我们再新建一个其他类,并将没有MYGame_APITest.h引入

#include "TEST.h"

UFUNCTION(BlueprintCallable, Category = "TestOtherFun")
static void TestOtherFun();

void UExorcistFunctionLibrary::TestOtherFun()
{
	UTEST::TestFun();
}
头像
编译依然ok
头像
项目中也一样正常使用
头像
这么说这东西可有可无?
头像
这得从他的作用说起了:
如果某个类没有使用 `xxx_api` 这样的宏,有几种可能的原因:
  1. 不需要导入和导出: 对于一些类,特别是那些不涉及跨库边界的纯内部实现,可能没有必要使用这样的宏。如果一个类只在单一的项目中使用,而不需要在其他项目或库中导入,那么就不需要使用导入和导出规范。

  2. 使用模板类或内联函数: 对于模板类或内联函数,它们的定义通常放在头文件中,这样编译器可以在每个使用它们的地方生成对应的代码,而不需要导入和导出。

  3. 宏定义中已经包含: 在一些情况下,类的导出规范可能已经在其他宏定义中包含,因此没有必要重复定义。

  4. 库或项目设计决策: 有时,项目或库的设计决策可能决定不使用导入和导出规范。这可能是因为项目的组织结构,构建过程,或者对于代码的特定要求。

头像
按这个说法,需要导入和导出时也就是编写的引入自定义插件时才可能出现链接库错误?
头像
实践一下就知道了!
  1. 新建一个插件,并在我们项目对应的build.cs加入插件模块
PrivateDependencyModuleNames.AddRange(
new string[]
    {
    "插件模块名"
   }
);
  1. 此时插件中没写插件名_API,编译后发生链接错误。
头像
看来确实是这么一回事。

参考链接

csdnopen in new windowUE4 "private: static class UClass...open in new window