我正在尝试编写包装程序代码,以便可以从C调用C ++例程。C++例程将在EXE文件中,而C例程将在DLL中。包装器代码将在单独的DLL中。
我将https://www.teddy.ch/c++_library_in_c/上的代码用作蓝图,但是在该示例中,所有代码最终都存储在单个EXE中。我已经编辑了包装器代码以生成DLL。
我现在正在尝试仅构建包装器代码DLL。包装程序代码DLL由三个文件组成:Wrapper.h,Wrapper.cpp和datatypes.h。尝试编译包装器代码时,出现“无效使用不完整类型”和“转发声明”错误。我知道我收到了错误,因为声明了“ wr_Class”,但未定义。但是,在哪里为类添加定义,以及如何将其定义为C程序?
为什么我所基于的代码没有得到那些错误?他们也没有定义类型。曾经但是他们的代码可以编译并运行。我知道这一点是因为我复制并运行了它。我看到的最大区别是,它们的代码生成一个可执行文件,而我的代码生成一个DLL。
我已经在Stack Overflow上寻找了答案。但是我在这里看到的包装器代码示例要么不在其自己的DLL中生成包装器代码,和/或它们也未定义Class结构。
Wrapper.h-我添加了引导行编号以供参考。
1. // *****************************************************************************
2. // * W r a p p e r . h *
3. // * *
4. // * C <----> Wrapper <----> C++ *
5. // * *
6. // * Programmer: Colleen Kobe *
7. // * *
8. // * Project: Small Business Innovative Research (SBIR) AF051-071, *
9. // * Phase 2 *
10. // * Date: July 09, 2018 *
11. // * Revised: tbd *
12. // * *
13. // * Description: This C header file contains the "wrapper" code that allows *
14. // * data to be passed between the C and C++ code in this *
15. // * project. *
16. // * *
17. // * This code was based on the code on: *
18. // * https://www.teddy.ch/c++_library_in_c/ *
19. // * *
20. // * Copyright : (c) 2018 Infrared Telemetrics, Inc. *
21. // *****************************************************************************
22.
23. #ifndef WRAPPER_H
24. #define WRAPPER_H
25.
26. // =============================================================================
27. // Compiler Options
28. // =============================================================================
29.
30. // Make sure functions are exported with C linkage under C++ compilers.
31. #ifdef __cplusplus
32. extern "C"
33. { // Export the code below with C linkage.
34. #endif // Close this block below.
35.
36.
37. #define DllExport __declspec (dllexport) // Add this code to a DLL.
38. #define DllImport __declspec (dllimport)
39. #define CALL_TYPE __stdcall
40.
41.
42. // =============================================================================
43. // External Header Files
44. // =============================================================================
45. #include "datatypes.h" // 2 a
46.
47. // =============================================================================
48. // Global Constants
49. // =============================================================================
50. // tbd
51.
52. // =============================================================================
53. // Global Types
54. // =============================================================================
55. typedef struct wr_Class_Ignored wr_Class; // "C" definition of Wrapper_Class.
56.
57.
58. // =============================================================================
59. // Global Variables
60. // =============================================================================
61. // wr_Class* Local_wr_Ptr; // Local pointer to Wrapper_Class.
62.
63.
64. // =============================================================================
65. // Prototypes
66. // =============================================================================
67. DllExport void CALL_TYPE wr_Initialize (void); // Perform initialization.
68.
69. DllExport wr_Class* CALL_TYPE wr_Create_New_Wrapper_Class (void); // Create a "new" wrapper class.
70.
71. DllExport void CALL_TYPE wr_Delete_Wrapper_Class (wr_Class* wr); // "Delete" a wrapper class.
72.
73. DllExport void CALL_TYPE wr_Terminate (void); // Perform termination.
74.
75. // .............................................................................
76. // Add these in later, one by one
77. // .............................................................................
78.
79. // void wr_Set_P07_NACK_Counter (wr_Class* wr, UInt32 n); // Set Qty_P07_NACKS_Received.
80. // UInt32 wr_Get_P07_NACK_Counter (wr_Class* wr); // Get Qty_P07_NACKS_Received.
81. // void wr_mf_Set_P08_SysID (wr_Class* wr, char SysID_ch [gd_bg_P08_QTY_DATAWORDS]); // Set P08 SysID.
82. // void wr_mf_Get_P08_SysID (wr_Class* wr, char * SysID_ch [gd_bg_P08_QTY_DATAWORDS]); // Set P08 SysID.
83.
84.
85. #ifdef __cplusplus
86. } // Export the following code with C linkage.
87. #endif
88.
89. #endif // WRAPPER_H
Wrapper.cpp-再次,我添加了引号以供参考
1. // *****************************************************************************
2. // * W r a p p e r . c p p *
3. // * *
4. // * C <----> Wrapper <----> C++ *
5. // * *
6. // * Programmer: Colleen Kobe *
7. // * *
8. // * Project: Small Business Innovative Research (SBIR) AF051-071, *
9. // * Phase 2 *
10. // * Date: July 09, 2018 *
11. // * Revised: tbd *
12. // * *
13. // * Description: This C header file contains the "wrapper" code that allows *
14. // * data to be passed between the C and C++ code in this *
15. // * project. *
16. // * *
17. // * This code was based on the code on: *
18. // * https://www.teddy.ch/c++_library_in_c/ *
19. // * *
20. // * Copyright : (c) 2018 Infrared Telemetrics, Inc. *
21. // *****************************************************************************
22.
23. // =============================================================================
24. // External Header Files
25. // =============================================================================
26. #include "Wrapper.h" // 5 w
27.
28. // =============================================================================
29. // Set Up Compiler Options
30. // =============================================================================
31. extern "C" {
32.
33. #define CALL_TYPE __stdcall
34.
35.
36. // =============================================================================
37. // Constants Public in This File
38. // =============================================================================
39. // tbd
40.
41. // =============================================================================
42. // Global Variables
43. // =============================================================================
44. UInt32 Qty_P07_NACKS_Received;
45. wr_Class* Local_wr_Ptr;
46.
47. // P07_NACK_Pkts P07_NACKS; // tbd -- add in later
48. // P07_Packet P07_Pkt; // tbd -- add in later
49.
50.
51. // +===========================================================================+
52. // | wr_Initialize |
53. // | |
54. // | Description: Performs the necessary initialization for the Wrapper |
55. // | code. |
56. // +===========================================================================+
57. DllExport void CALL_TYPE wr_Initialize (void)
58. {
59. Local_wr_Ptr = wr_Create_New_Wrapper_Class (); // Create a new Local_wr_Ptr;
60. } // wr_Initialize
61.
62.
63. // +===========================================================================+
64. // | wr_Create_New_Wrapper_Class |
65. // | |
66. // | Description: Creates a new instance of Wrapper_Class, and returns a |
67. // | pointer to it. |
68. // +===========================================================================+
69. DllExport wr_Class* CALL_TYPE wr_Create_New_Wrapper_Class (void)
70. {
71.
72. wr_Class* temp_wr_ptr; // for debugging--shorten this code when it's clear that it works.
73. temp_wr_ptr = new wr_Class;
74.
75. return (temp_wr_ptr);
76.
77. } // wr_Create_New_Wrapper_Class
78.
79.
80. // +===========================================================================+
81. // | wr_Delete_Wrapper_Class |
82. // | |
83. // | Description: Deletes an existing instance of Wrapper_Class. |
84. // +===========================================================================+
85. DllExport void CALL_TYPE wr_Delete_Wrapper_Class (wr_Class* wr)
86. {
87. delete wr;
88. } // wr_Delete_Wrapper_Class
89.
90.
91. // +===========================================================================+
92. // | wr_Terminate |
93. // | |
94. // | Description: Performs the necessary termination for the Wrapper code. |
95. // | code. |
96. // +===========================================================================+
97. DllExport void CALL_TYPE wr_Terminate (void)
98. {
99. wr_Delete_Wrapper_Class (Local_wr_Ptr); // Delete our Local_wr_Ptr.
100. } // wr_Terminate
101.
102.
103. // .............................................................................
104. // Add these in later, one by one
105. // .............................................................................
106.
107. // void wr_Class_int_set (wr_Class* wr, int i)
108. // {
109. // wr->int_set (i);
110. // }
111.
112. // int wr_Class_int_get (wr_Class* wr)
113. // {
114. // return wr->int_get ();
115. // }
116.
117. // void wr_mf_Set_SysID (wr_Class* wr, char SysID_ch [gd_bg_P08_QTY_DATAWORDS])
118. // {
119. // // mf_Set_SysID (char SysID_ch [gd_bg_P08_QTY_DATAWORDS]);
120. // ;
121. // }
122.
123. } // extern "C"
datatypes.h-我添加了引导行编号以供参考。您可能不需要这个,但是无论如何都在这里。
1. // *****************************************************************************
2. // * d a t a t y p e s . h *
3. // * *
4. // * Programmer: Colleen Kobe *
5. // * *
6. // * Project: Small Business Innovative Research (SBIR) AF051-071 *
7. // * Date: March 14, 2016 *
8. // * Revised: July 10, 2018 *
9. // * Revised: tbd *
10. // * *
11. // * Description: This C header file contains public declarations for *
12. // * general use data types. *
13. // * *
14. // * I created these type names to establish with absolute *
15. // * certainty the range and bit length of an integer variable. *
16. // * *
17. // * Copyright: (c) 2018 Infrared Telemetrics, Inc. *
18. // *****************************************************************************
19.
20. #ifndef DATATYPES_H
21. #define DATATYPES_H
22.
23. // =============================================================================
24. // Set Up Compiler Options
25. // =============================================================================
26.
27. /* Make sure functions are exported with C linkage under C++ compilers. */
28. #ifdef __cplusplus
29. extern "C"
30. { // Export the following code with C linkage.
31. #endif // Notice that this block is still open. It is closed below.
32.
33. #define DllExport __declspec (dllexport)
34. #define DllImport __declspec (dllimport)
35. #define CALL_TYPE __stdcall
36.
37. // =============================================================================
38. // External Header Files
39. // =============================================================================
40. #include <stdint.h> // 1 c3
41.
42. // =============================================================================
43. // Global Constants
44. // =============================================================================
45. // None.
46.
47. // =============================================================================
48. // Global Types
49. // =============================================================================
50.
51. // --------------------------------------------------------------------------------
52. // Range
53. // --------------------------------------------------------------------------------
54. typedef signed char Int08; // -2** 7 .. (2** 7) - 1 [ -128 .. 127]
55. typedef short Int16; // -2**15 .. (2**15) - 1 [ -32,768 .. 32,767]
56. typedef int Int32; // AKA long // -2**31 .. (2**31) - 1 [ -2,147,483,648 .. 2,147,483,647]
57. typedef int64_t Int64; // AKA long long // -2**63 .. (2**63) - 1 [ -9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807]
58.
59. typedef unsigned char UInt08; // 0 .. (2** 8) - 1 [ 0 .. 255]
60. typedef unsigned short UInt16; // 0 .. (2**16) - 1 [ 0 .. 65,535]
61. typedef unsigned int UInt32; // AKA DWORD // 0 .. (2**32) - 1 [ 0 .. 4,294,967,295]
62. typedef uint64_t UInt64; // AKA unsigned long long // 0 .. (2**64) - 1 [ 0 .. 18,446,744,073,709,551,615]
63.
64.
65. // =============================================================================
66. // Prototypes
67. // =============================================================================
68. // None.
69.
70. #ifdef __cplusplus
71. } // export the following code with C linkage.
72. #endif
73.
74. #endif // DATATYPES_H
Buildlog.txt
1. C:\Windows\system32\cmd.exe /C C:/MinGW/bin/mingw32-make.exe -j4 SHELL=cmd.exe -e -f "Wrapper_Code.mk" MakeIntermediateDirs && C:/MinGW/bin/mingw32-make.exe -j4 SHELL=cmd.exe -e -f "Wrapper_Code.mk" all
2. ----------Building project:[ Wrapper_Code - Debug ]----------
3. C:/MinGW/bin/g++.exe -c "F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp" -g -O0 -Wall -c -o ./Debug/Wrapper.cpp.o -I. -IC:\MinGW\include -IC:\wxWidgets\include -I. -I..\Background -I..\Behind_the_Scenes -I..\Main -I..\Resources -I..\Run_Here -I..\Wrapper_Code
4. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp: In function 'wr_Class* wr_Create_New_Wrapper_Class()':
5. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp:73:25: error: invalid use of incomplete type 'wr_Class {aka struct wr_Class_Ignored}'
6. temp_wr_ptr = new wr_Class;
7. ^~~~~~~~
8. In file included from F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp:26:0:
9. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.h:55:17: note: forward declaration of 'wr_Class {aka struct wr_Class_Ignored}'
10. typedef struct wr_Class_Ignored wr_Class; // "C" definition of Wrapper_Class.
11. ^~~~~~~~~~~~~~~~
12. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp: In function 'void wr_Delete_Wrapper_Class(wr_Class*)':
13. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp:87:13: warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]
14. delete wr;
15. ^~
16. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp:85:72: warning: 'wr' has incomplete type
17. DllExport void CALL_TYPE wr_Delete_Wrapper_Class (wr_Class* wr)
18. ^~
19. In file included from F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp:26:0:
20. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.h:55:17: note: forward declaration of 'struct wr_Class_Ignored'
21. typedef struct wr_Class_Ignored wr_Class; // "C" definition of Wrapper_Class.
22. ^~~~~~~~~~~~~~~~
23. F:/SBIR_Phase_II_A/Wrapper_Code/Wrapper.cpp:87:13: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
24. delete wr;
25. ^~
26. mingw32-make.exe: *** [Debug/Wrapper.cpp.o] Error 1
27. Wrapper_Code.mk:101: recipe for target 'Debug/Wrapper.cpp.o' failed
28. ====1 errors, 7 warnings====
如何解决“无效使用不完整类型”警告?我得到它是因为我正在构建DLL而不是EXE吗?如果是这样,关于如何声明Wrapper类,以便我能够成功处理C和C ++编译器和链接器,我还有其他选择吗?
建议?有评论吗?
编码环境:
Windows 10
C & C++
MinGW / gcc / g++
wxWidgets
CodeLite v12.0.3
谢谢! 科琳
答案 0 :(得分:0)
在Wrapper.cpp中,不存在struct wr_Class_Ignored
的定义,因此您无法访问其任何成员。
此类的实际定义可能存在于单独的标头中,因此请将该标头包含在Wrapper.cpp中。您将看到从其建模的示例代码执行的操作相同。