【问题标题】:Alternative to symlink in C++ BuilderC++ Builder 中符号链接的替代方案
【发布时间】:2015-08-25 23:44:23
【问题描述】:

我目前正在尝试在 C++ Builder 中集成为 UNIX 编写的 C 代码。但是部分代码使用了函数符号链接:

if(!fname
|| (use_real_copy ? real_copy(path, fname) : symlink(path, fname))

我不知道如何替换它,因此它可以在 Windows 64 位的 C++ Builder 中工作,我发现函数 CreateSymbolicLinkW 和 CreateSymbolicLinkA 似乎与 Windows 等效,但 C++ Builder 找不到它们。

您知道如何解决这个问题吗?

谢谢。

【问题讨论】:

  • 您是否尝试过使用 CreateSymbolicLink(注意缺少 A 或 W)? A/W 是 API 中函数的 ansi/wide 版本,但是你通常调用一个没有任何东西,所以编译器会根据项目选择调用哪一个。
  • 你说的找不到是什么意思?是编译器还是链接器?其实错误信息是什么?
  • 感谢您提供此信息。是的,我尝试过使用 CreateSymbolicLink,但它是同样的问题,它是一个“隐式声明 [...]”。我尝试包含“windows.h”,但它在此文件中引发了错误。

标签: c c++builder symlink


【解决方案1】:

CreateSymbolicLink() 在所有基于 VCL 的项目中声明在 winbase.h 中,即 #include'd by windows.h,即 #include'd by vcl.h。如果您没有创建 VCL 项目,请确保您的代码中有 #include <windows.h> 语句。无论哪种方式,还要确保 _WIN32_WINNT 至少定义为 0x0600 (Vista+)。

如果编译器仍然抱怨 CreateSymbolicLink() 未定义,那么您必须使用旧版本的 C++Builder(CreateSymbolicLink() 在 C++Builder 2007 中添加到 C++Builder 的 winbase.h 副本中) ,在这种情况下,您必须在自己的代码中手动声明CreateSymbolicLink(),例如:

#define SYMBOLIC_LINK_FLAG_DIRECTORY            (0x1)

#define VALID_SYMBOLIC_LINK_FLAGS  SYMBOLIC_LINK_FLAG_DIRECTORY // & whatever other flags we think of!

WINBASEAPI
BOOLEAN
APIENTRY
CreateSymbolicLinkA (
    __in LPCSTR lpSymlinkFileName,
    __in LPCSTR lpTargetFileName,
    __in DWORD dwFlags
    );
WINBASEAPI
BOOLEAN
APIENTRY
CreateSymbolicLinkW (
    __in LPCWSTR lpSymlinkFileName,
    __in LPCWSTR lpTargetFileName,
    __in DWORD dwFlags
    );
#ifdef UNICODE
#define CreateSymbolicLink  CreateSymbolicLinkW
#else
#define CreateSymbolicLink  CreateSymbolicLinkA
#endif // !UNICODE

但是您还有另一个问题需要解决 - 该版本的 C++Builder 也不会在其 kernel32.lib 的副本中包含 CreateSymbolicLinkACreateSymbolicLinkW 符号,用于链接到 kernel32.dll 中的导出函数。因此,您必须从包含这些符号的现代 kernel32.dll 创建一个新的 .lib 导入库,然后将其添加到您的项目中。此时,在运行时使用GetProcAddress() 动态加载CreateSymbolicLink() 可能会更容易:

typedef BOOLEAN (APIENTRY *LPFN_CSL)(LPCTSTR, LPCTSTR, DWORD);

LPFN_CSL lpCreateSymbolicLink = (LPFN_CSL) GetProcAddress(GetModuleHandle(TEXT("kernel32")),
    #ifdef UNICODE
    "CreateSymbolicLinkW"
    #else
    "CreateSymbolicLinkA"
    #endif
);
if (lpCreateSymbolicLink)
{
    // use lpCreateSymbolicLink(...) as needed...
}

这也将允许您的代码在 XP 和更早版本上运行(如果需要),因为在 Vista 中添加了CreateSymbolicLink()

【讨论】:

  • 在我的 C 文件中包含 实际上会引发错误,rpcdcep.h 中的“未知 'OUT' 类型名称”,我不知道为什么。我在同一个项目中使用 ,但是在 C++ 文件中。
猜你喜欢
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
相关资源
最近更新 更多