簡體   English   中英

如何在 C 中運行時更改文件的路徑?

[英]How To Change Path of a File At Runtime In C?

我必須在運行時更改自定義頭文件的宏給出的路徑。 假設我有一個目錄,其中存儲了所有自定義數據結構Path: E:\Programming Files\Code\C\Custom Headers Custom Headers文件夾有一些子文件夾,我的目錄工作流程是這樣的:

Custom Headers
      |
      |> Array Structure
      |       |
      |       |> Integer_Array.c
      |       |
      |       |> Float_Array.c
      |       |
      |       |> Char_Array.c
      |       |
      |       |> Arrays.h
      |
      |> Stack Structure
      |       |
      |       |> Integer_Stack.c
      |       |
      |       |> Float_Stack.c
      |       |
      |       |> Char_Stack.c
      |       |
      |       |> Stack.h
      |
      |> Queue Structure
      |       |
      |       |> Integer_Queue.c
      |       |
      |       |> Float_Queue.c
      |       |
      |       |> Char_Queue.c
      |       |
      |       |> Queue.h
      |
      |> Structures.h
      |

Arrays.hStack.hQueue.h中定義了結構的路徑。 例如,在Arrays.h文件中:

#define Int_Array "E:\Programming Files\Code\C\Custom Headers\Array Structure\Integer_Array.c"
#define Float_Array "E:\Programming Files\Code\C\Custom Headers\Array Structure\Float_Array.c"
#define Char_Array "E:\Programming Files\Code\C\Custom Headers\Array Structure\Char_Array.c"

就像Stack.hQueue.h文件也被寫入一樣。 最后一個是Structures.h

#define Array "E:\Programming Files\Code\C\Custom Headers\Array Structure\Arrays.h"
#define Stack "E:\Programming Files\Code\C\Custom Headers\Stack Structure\Stack.h"
#define Queue "E:\Programming Files\Code\C\Custom Headers\Queue Structure\Queue.h"

#include Array
#include Stack
#include Queue

使用這些文件,我通過目錄建立了連接網絡。 因為它,我可以在不提供地址的情況下將所有結構包含在Custom Headers文件夾中。 例如: Example.c (其他目錄中的文件):::

#include <stdio.h>
#include "E:\Programming Files\Code\C\Custom Headers\Structures.h"
#include Int_Array
#include Int_Stack
#include Int_Queue

int main()
{
  printf("Hello World!");
  return 0;
}

當在任何需要的文件中包含我的結構時,這只是為了簡單。

問題是我無法在任何情況下修改路徑。 當我包含Structures.h文件時,是否有任何解決方案可以更改所有路徑。 Problem.c

#include <stdio.h>
#define ROOT_PATH "E:\Programming\C" \\Is There Any Thing Like This Can Modify The Value of All Defined Macros.
#include "E:\Programming Files\Code\C\Custom Headers\Structures.h"

int main()
{
  return 0;
}

問題是您從根本上誤用了宏和#include 雖然此示例可以編譯,但適當地使用它們將為您提供所需的靈活性。

像您描述的可移植、獨立於項目的代碼最好作為庫來實現。 庫是一個編譯文件,您的程序可以在運行時加載(您也可以直接將它們捆綁在一起,這稱為靜態鏈接)。 您可以與多個項目共享一個庫。 事實上,你已經在這樣做了! #include <stdio.c>的調用包括一個庫。

你有頭文件,它定義了直接#include c 文件的宏。 這在幾個方面是不正確的。

C 庫結構快速指南

C 代碼存儲在.h.c文件中。 .h文件包含所有代碼的簽名,但只有.c存儲實現。 .so文件是捆綁包。

從您的代碼中,假設我要訪問三個庫,一個 int 數組、一個 int 堆棧和一個 int 隊列。 這是custom lib/int_array.c

#include "int_array.h"
#include <stdlib.h>

struct int_array {
    int * data,
    int length;
};

struct int_array * new_int_array(int length) {
    // Code here, etc.
}

void hidden_func(void) {
    ...
}

custom_lib/int_array.h

#ifndef CUSTOM_LIB_INT_ARRAY_H
#define CUSTOM_LIB_INT_ARRAY_H

struct int_array;

struct int_array * new_int_array(int length);

#endif

頭文件包含函數和類型的原型。 這些沒有定義,但接口是定義的。 這是其他代碼需要查看才能調用代碼並正確使用它的所有信息。

在c文件中,實現了代碼。 只有類型才有意義。 現在您的代碼已准備好,您可以將其打包成一個可共享的對象,其他程序可以在運行時接收並與之鏈接。

首先,我們編譯代碼:

gcc -c -fpic int_array.c

這會生成一個名為int_array.o的文件。 現在我們需要將它打包成可共享的東西。 我們這樣做:

gcc -shared -o libint_array.so int_array.o

這將產生一個libint_array.so 我們完了! 現在我們的代碼可以在其他項目中使用了。

在一個完全獨立的文件夾中,我們編寫proj/main.c

#include "int_array.h"

int main() {
   // use int_array
}

為了編譯它,我們需要告訴編譯器在哪里尋找對象。 它會自動查找一個位置列表,因此我們可以

1.) 將您的庫復制到已選中的位置。 這稱為您的庫路徑。 在 linux 上,它通常是/usr/lib以及其他一些。 如果您將.so放在所需的文件夾中,它將出現。

2.) 將您的庫添加到搜索路徑。 您可以通過將-L /path/to/.so/folder添加到編譯器來執行此操作。

我假設您選擇了選項 1。

現在,你像這樣編譯你的項目:

gcc main.c -lint_array

這將生成一個在運行時鏈接到 int_array 的二進制文件。

有用的屬性

您可以改為在默認搜索路徑中創建一個文件夾來創建結構。 例如,創建文件夾/usr/lib/custom ,並將您的 .so 文件放入此文件夾中。 這將讓您執行#include <custom/int_array.h> ,這將清楚地顯示您何時使用自定義代碼。

在運行時,您可以更改編譯器查找庫的位置,並可以選擇鏈接的版本。

此外,如果您在庫中發現錯誤,您可以修復它,並更新.so 這將導致所有項目立即使用帶有修復程序的正確庫。 使用您的方法,您必須重新編譯使用該庫的每個項目。

與您的方法的重要區別

您的方法的問題是您包含 .c 文件而不是 .h 文件。 當像這樣包含 .c 文件時,它會有效地將文件中的所有代碼直接復制到您的源代碼中。 問題是這可能會帶來不需要的函數和全局變量,並且每次調用時都會復制它的代碼。

例如,在上面的例子中, int_array.c定義了一個名為void hidden_func(void);的文件。 . main.c無法訪問該功能。 這是因為僅導出.h文件中的符號。 這允許您使用您不想共享的輔助函數。

此外,如果您使用您的方法在程序中多次包含一個文件,則每次都會復制代碼。 這意味着您的最終代碼將比應有的大幾倍,因為每個函數將被包含多次。

當使用 shared_libraries 包含代碼時,它的源代碼只加載一次。

概括

要更改代碼以遵循此模式,您可以編譯.so ,如上所示。 要更改包含的版本,您可以使用-L標志來更改編譯器查找.so的位置。 它有

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM