Как я могу разделить свой код на C в разных файлах

#c #visual-c

Вопрос:

Я собираюсь разделить свой код на C на несколько файлов, так как сейчас в нем более 3000 строк, и я хочу упорядочить свой код. Вот упрощенная версия моего кода в одном файле:

lib.c

 #if defined(_WIN32)
#  define MAIN_EXPORT_API __declspec(dllexport)
#else
#  define MAIN_EXPORT_API
#endif

typedef struct Vertex Vertex;
typedef struct Element Element;
typedef struct Grid Grid;

struct Vertex {
    int index;
    Element *element;
};
struct Element {
    int index;
    Vertex vertex;
};
struct Grid {
    Vertex *vertex;
    Element *element;
};

MAIN_EXPORT_API Vertex Vertex_init (int index) {
    Vertex vertex;
    vertex.index = index;
    return vertex;
}
MAIN_EXPORT_API Element Element_init (int index, Vertex *vertexPtr) {
    Element element;
    element.index = index;
    vertexPtr->element = amp;element;
    return element;
}
MAIN_EXPORT_API Grid Grid_init () {
    Grid grid;
    Vertex vertex = Vertex_init(0);
    Element element = Element_init(0, amp;vertex);
    grid.vertex = amp;vertex;
    grid.element = amp;element;
    return grid;
}
 

Затем я попытался начать разбивать его следующим образом:

new_lib.h

 #if defined(_WIN32)
#  if defined(LIB_EXPORTS)
#    define LIB_EXPORT_API __declspec(dllexport)
#  else
#    define LIB_EXPORT_API __declspec(dllimport)
#  endif
#else
#  define LIB_EXPORT_API
#endif

typedef struct Vertex Vertex;
typedef struct Element Element;
typedef struct Grid Grid;

struct Vertex {
    int handle;
    Element *element;
};
struct Element {
    int handle;
    Vertex vertex;
};
struct Grid {
    Vertex *vertex;
    Element *element;
};
 

new_lib.c

 #define LIB_EXPORTS
#include "new_lib.h"

Element Element_init (int handle, Vertex *vertexPtr) {
    Element element;
    element.handle = handle;
    vertexPtr->element = amp;element;
    return element;
}
Grid Grid_init () {
    Grid grid;
    Vertex vertex = Vertex_init(0);
    Element element = Element_init(0, amp;vertex);
    grid.vertex = amp;vertex;
    grid.element = amp;element;
    return grid;
}
 

вершина.h

 #if defined(_WIN32)
#  if defined(VERTEX_EXPORTS)
#    define VERTEX_EXPORT_API __declspec(dllexport)
#  else
#    define VERTEX_EXPORT_API __declspec(dllimport)
#  endif
#else
#  define VERTEX_EXPORT_API
#endif

#include "lib.h"

VERTEX_EXPORT_API Vertex Vertex_init (int handle);
 

вершина.c

 #define VERTEX_EXPORTS
#include "vertex.h"

Vertex Vertex_init (int handle) {
    Vertex vertex;
    vertex.handle = handle;
    return vertex;
}
 

И когда я его компилирую, я получаю:

 C:>
C:>cl /nologo /DDLL vertex.c /link /NOLOGO /DLL /OUT:vertex.dll
vertex.c
   Creating vertex.lib library and vertex.exp object 

C:>cl /nologo /DDLL new_lib.c /link /NOLOGO /DLL /OUT:new_lib.dll vertex.lib
new_lib.c
new_lib.c(12): error C2440: 'initializing': cannot convert from 'int' to 'Vertex'

C:>
C:>
 

Кто-нибудь может помочь?

Комментарии:

1. Вы можете разделить его, как вам нравится.:)

2. Проблема в том, что new_lib.c в нем нет объявления Vertex_init , потому что вы не включили файл vertex.h заголовка.

3. Однако есть и другие, гораздо более серьезные проблемы, такие как хранение и, по сути, возврат указателей на локальные переменные. Как только Grid_init функция возвращается, все локальные переменные, такие как vertex и element , выходят за рамки, и их срок службы заканчивается. Любой указатель на них станет недействительным.

4. Эта версия, которую я показал, является более короткой версией моей программы. Там я использую malloc всякий раз, когда мне нужно использовать указатели, и в конце программы я перебираю все эти указатели и освобождаю их. Но спасибо тебе.

5. @GustavoExel: Проблема в том, что вы неправильно сократили его. Ошибка связана с вашим initializing методом, но в вашем вопросе здесь нет initializing метода.


Ответ №1:

Когда мы разделяем код на языке си, одна из самых важных вещей, на которую следует обратить внимание, — это компиляция. Когда код попадает в разные файлы, каждый из файлов должен быть скомпилирован отдельно, это поможет в любом случае внесения изменений в код, так как только измененный файл должен быть перекомпилирован. Основной способ сделать это таков: сначала создайте файл makefile, который включает компиляцию для каждого файла, для которого есть пример файла makefile как такового:

пример makefile

 myprog: f1.o f2.o f3.o
        gcc -g -Wall -ansi -pedantic  f1.o f2.o f3.o -o myprog -lm      
f1.o:f1.c data.h
        gcc -c -Wall -ansi -pedantic  f1.c -o f1.o -lm
f2.o:f2.c data.h
        gcc -c -Wall -ansi -pedantic  f2.c -o f2.o -lm
f3.o:f3.c data.h
        gcc -c -Wall -ansi -pedantic  f3.c -o f3.o -lm
 

В этом примере makefile мы можем увидеть, как включить каждый из файлов, и как включить их файл .h по отдельности, если это необходимо.

Комментарии:

1. Не могли бы вы, пожалуйста, использовать правильную пунктуацию, а также заглавные буквы в начале каждого предложения? Английский не является родным языком для многих пользователей StackOverflow, пропуск важных частей английского письма затрудняет их понимание текста.

2. Я не думаю, что файлы makefile являются нормой для Visual C , не так ли?

3. это не мой ответ был только для языка си. извините