生如夏花133 发表于 2019-10-15 19:20:53

C语言 动态链接库

大概的了解了一下C,但是还是看不太懂代码,也不太明白调用动态链接库的一系列过程和原理
请问有人愿意帮帮忙嘛~
如下是test.c文件



// Test of the SWMM5 C Interfacing functions

// This is a command line executable that takes the name
// of a SWMM input file as its only command line argument
// and produces a time series listing to the console of the
// following system output results: total rainfall, total
// runoff and total outfall flow.

// This file must be compiled along with swmm5_iface.c
// and swmm5.h, and linked with swmm5.dll and swmm5.lib.

#include <stdio.h>
#include "swmm5_iface.h"

int main(int argc, char *argv[])
{
   int i, r;
   float x, y, z;
   char rptfile[] = "tmp.rpt";
   char outfile[] = "tmp.out";

// Check if a SWMM input file name is provided
   if (argc < 2)
   {
      printf("\nNo file name was provided.\n");
      return 0;
   }

// Run the SWMM analysis
   r = RunSwmmDll(argv, rptfile, outfile);
   if (r > 0)
   {
      printf("\nSWMM run was unsuccessful; error code = %d\n", r);
   }
   else
   {
   // Open outfile as a SWMM output file
      r = OpenSwmmOutFile(outfile);
      if (r == 1)
      {
         printf("\nInvalid results in SWMM output file.\n");
      }
      else if (r == 2)
      {
         printf("\nFile is not a SWMM output file.\n");
      }
      else
      {
         printf("\nTime       Total   Total   Total");
         printf("\nPeriodRainfall    Runoff   Outflow");
         printf("\n====================================");
         for (i=1; i<=SWMM_Nperiods; i++)
         {
             GetSwmmResult(3, 0, 1, i, &x);
             GetSwmmResult(3, 0, 4, i, &y);
             GetSwmmResult(3, 0, 11, i, &z);
             printf("\n%6d%8.2f%8.2f%8.2f", i, x, y, z);
         }
         CloseSwmmOutFile();
      }
   }
   remove(rptfile);
   remove(outfile);
   return 0;
}

xypmyp 发表于 2019-10-16 09:21:06

If you wish to know how DLL works in deep, I suggest you to learn PE Struct (Export table, Import table), than you will see how EXE find the DLL function and how it using it.
In my point of view, those code are using static link library instead of DLL, you should have a look of its' different i guess.

You may have to know what does int argc, char *argv[] mean. As the code are using them.

These code are using others function in "swmm5_iface.h", try to step into it, it's hard to tell what the code means in only one C file.{:10_257:}

生如夏花133 发表于 2019-10-16 15:06:49

xypmyp 发表于 2019-10-16 09:21
If you wish to know how DLL works in deep, I suggest you to learn PE Struct (Export table, Import ta ...

这是swmm5.h的代码
请问#ifndef SWMM5_H
#define SWMM5_H
这两行代码有什么意义?
ifndef意思是如果无定义,define是宏定义,可是后面为什么缺少了字符串?

还有就是接着的define WINDOWS,我也不太能理解是什么含义?
我大概知道最后那部分内容就是调用dll(如:#define DLLEXPORT __declspec(dllexport) __stdcall 定义其为 DLLEXPORT,但是后面为什么要出现
#else
#define DLLEXPORT


// --- use "C" linkage for C++ programs

#ifdef __cplusplus
extern "C" {
#endif

......

#ifdef __cplusplus
}   // matches the linkage specification from above */
#endif
这部分是格式嘛?不太理解用法,课本上貌似没找到。



//-----------------------------------------------------------------------------
//   swmm5.h
//
//   Project: EPA SWMM5
//   Version: 5.1
//   Date:    03/24/14(Build 5.1.001)
//            06/30/16(Build 5.1.011)
//   Author:L. Rossman
//
//   Prototypes for SWMM5 functions exported to swmm5.dll.
//
//-----------------------------------------------------------------------------
#ifndef SWMM5_H
#define SWMM5_H

// --- define WINDOWS

#undef WINDOWS
#ifdef _WIN32
#define WINDOWS
#endif
#ifdef __WIN32__
#define WINDOWS
#endif

// --- define DLLEXPORT

#ifdef WINDOWS
#define DLLEXPORT __declspec(dllexport) __stdcall
#else
#define DLLEXPORT
#endif

// --- use "C" linkage for C++ programs

#ifdef __cplusplus
extern "C" {
#endif

intDLLEXPORT   swmm_run(char* f1, char* f2, char* f3);
intDLLEXPORT   swmm_open(char* f1, char* f2, char* f3);
intDLLEXPORT   swmm_start(int saveFlag);
intDLLEXPORT   swmm_step(double* elapsedTime);
intDLLEXPORT   swmm_end(void);
intDLLEXPORT   swmm_report(void);
intDLLEXPORT   swmm_getMassBalErr(float* runoffErr, float* flowErr,
               float* qualErr);
intDLLEXPORT   swmm_close(void);
intDLLEXPORT   swmm_getVersion(void);
intDLLEXPORT   swmm_getError(char* errMsg, int msgLen);                      //(5.1.011)
intDLLEXPORT   swmm_getWarnings(void);                                       //(5.1.011)

#ifdef __cplusplus
}   // matches the linkage specification from above */
#endif

#endif

xypmyp 发表于 2019-10-16 16:01:40

本帖最后由 xypmyp 于 2019-10-16 16:07 编辑

Q1.#define DLLEXPORT __declspec(dllexport) __stdcall

They call this as "File Guards", to avoid multiple declaration with the same header.
#ifndef HEADER_H_
#def HEADER_H_
#include "header.h"
...
#endif


Q2.#ifdef __cplusplus extern "C" {
It's for including C Headers in C++ Code
If you want to use a C library with its own defining header that was intended for C compilers, you can include the header in extern “C" brackets:
extern "C" {
    #include "header.h"
}
I don't mixed C && C++ program just yet, I am not sure how it's works. But it clearly notice that the author try to include a C Library into C++ program.

Those question related to "File Guards"

In general #define directive allows the definition of macros within your source code. These macro definitions allow constant values to be declared for use throughout your code.
Macro definitions are not variables and cannot be changed by your program code like variables. You generally use this syntax when creating constants that represent numbers, strings or expressions.
It's for compiler to replace those words when compiling, it easier for people to read.
页: [1]
查看完整版本: C语言 动态链接库