Re: [問題] 自製DLL的struct問題

看板C_and_CPP (C/C++)作者 (卡卡獸)時間10年前 (2015/06/25 01:08), 編輯推噓0(0044)
留言44則, 4人參與, 最新討論串2/2 (看更多)
剛好我也什麼都不懂,討論一下。 ※ 引述《petercoin (彼得幣)》之銘言: < 恕刪 > : 在IO.h內定義一個struct如下 : typedef struct _ReadData : { : char *A; : int B; : ... : } READDATA; < 恕刪 > : 我目前想到的方法是重新在MyDll.h內定義一個名字不一樣但是內容一樣的struct : 例如 : typedef struct _ReadData1 : { : char *A; : int B; : ... : } READDATA1; 先提關鍵字 : dllexport , dllimport , 重點就這兩個 。 用同一份程式碼,配合 macro define 切換,以下贅述憑印象,請自行抓重點, 若有誤也請不吝指正。 -------------------------------------- 我不知道你用的 IDE / compiler 是哪套 , 只好以我比較熟的 visual studio 來講 , VS 到後面是以 solution 概念為主軸 , 一個 solution 可以有多個 project , 正常而言我的主程式 (exe) 會是其中一個 project , 命為 MainProj , 其他可能有數個產生 dll 的 project , 這些講其中一個 , 命為 IOProj。 在 IOProj 裡就是你放的 MyDll.h/.cpp , IO1.h/.cpp IO2.h/.cpp 正常共用 (其他 proj 也用得到) 的 struct/class 宣告, 應是抽出來集中放到一個 .h 裡面,然後宣告時動了點手腳 , 以下是範例 // ---------- myio.h ---------- #pragma once #ifndef EXPORT_IO_API #define IO_API __declspec ( dllimport ) #else #define IO_API __declspec ( dllexport ) #endif struct IO_API IOData { unsigned int m_addr; unsigned char m_val; }; int IO_API set_data(IOData * pdata) ; // implement in myio.cpp // ---------- myio.cpp ---------- // #include "stdafx.h" // for vs #include "myio.h" int IO_API set_data( IOData * pdata ) { if(pdata == NULL) return 0; pdata->m_addr = 0x80000000; pdata->m_val = 0xCC; return 1; } 先分析一下 .h 講的東西, 若不定義 EXPORT_IO_API , 便可將 IODATA 與其他 function import (Main Project); 若定義出 EXPORT_IO_API , 便可將 IODATA 與其他 function export (IO Project); 這時候就借用了 VS IDE 的巨集定義功能, 在 IO Project 之專案屬性->組態屬性->c/c++->前置處理,前置處理定義新增一個 EXPORT_IO_API 即可,這個 header 對 IO Project 而言就是做 dll export ; 若你習慣用 command line 編譯或是 IDE 不支援前置處理設定的話, 大概就是從 compiler command line 那裡做前置處理了,詳細略(還不是因為懶得查XD)。 而在 Main Project ,只需要 include 到 myio.h 即可 , 而且確保 EXPORT_IO_API 是沒被定義過的就行了 (正常應該是不會,除非衝名) include 方式有很多種,像是 #include "..\\IO\\myio.h" , 或是直接在 IDE 裡面做額外的 include 目錄都行。 這種方式的好處是,最後的確只需要維護一份 .h / .cpp 便可, 不會因為 Project 不同,導致 myio.h , myio.cpp 到處亂飛, 多了兩個問題變成是專案相依性 與常看到 "無法解析的外部符號 @XY ..... " 等等, 不過這兩個問題應該是你原本架構都有機會遇到的。 以上,若我敘述有誤,請不吝指定。 或有其他較佳之維護方式,也歡迎提出討論。 -- 「自從我學了 C# , 人都變聰明 , 考試都考一百分」 「自從我學了 VB , 皮膚都變好 , 人也變漂亮了 」 「自從我學了 Java , 明顯變壯 , 個子也變高了 」 「自從我學了 C++ , 內分泌失調 , 頭都禿了... 」 < Kuso 星爺語錄 > -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.195.169.158 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1435165717.A.A92.html

06/25 09:13, , 1F
意思是說只要有dllexport的struct 就算不放在IO.h
06/25 09:13, 1F

06/25 09:14, , 2F
而只放在MyDll.h 一樣可以直接在IO.cpp裡面使用是嗎?
06/25 09:14, 2F

06/25 11:24, , 3F
我目前是用VC 但是exe跟dll是不同solution
06/25 11:24, 3F

06/25 11:25, , 4F
MyDll.cpp只提供Set或Get的介面 功能的實作在IO.cpp
06/25 11:25, 4F

06/25 11:25, , 5F
所以才會有struct要共用的問題QQ
06/25 11:25, 5F

06/25 11:50, , 6F
這是正解, 然後樓上你需要的應該是宣告在 IO.h, 然後在
06/25 11:50, 6F

06/25 11:50, , 7F
MyDLL.h 加上 #include "IO.h"
06/25 11:50, 7F

06/25 12:07, , 8F
其實重點就是在於 MyDLL.h 要不要 include 其他人的問題
06/25 12:07, 8F

06/25 12:08, , 9F
跟這篇的重點其實不太一樣. (我是說原 po 的疑問)
06/25 12:08, 9F

06/25 12:08, , 10F
要 include 的話, 就不會有原 po 的問題.
06/25 12:08, 10F

06/25 12:08, , 11F
接著才是 dllimport 跟 dllexport 的問題
06/25 12:08, 11F

06/25 12:09, , 12F
還是說其實是我理解有問題 Orz..
06/25 12:09, 12F

06/25 12:23, , 13F
其實我的問題是如果寫在IO.h 那使用dll的人如何知道
06/25 12:23, 13F

06/25 12:23, , 14F
這個struct的內容有什麼?
06/25 12:23, 14F

06/25 12:24, , 15F
因為我只打算把MyDll.h丟給使用者 不打算公開IO.h
06/25 12:24, 15F

06/25 12:25, , 16F
我理解阿. 你要 include 其他人就是要把其他人拿進來
06/25 12:25, 16F

06/25 12:26, , 17F
你不想的話要怎麼辦. 這才是你的問題.
06/25 12:26, 17F

06/25 12:27, , 18F
我的意見就是要嘛把 A.h 給別人. 要嘛就包起來
06/25 12:27, 18F

06/25 12:27, , 19F
還是乾脆把STRUCT寫成註解放在MyDll.h...XD
06/25 12:27, 19F

06/25 12:27, , 20F
如果你連 A.h 都不想給別人. 那要說明一下理由
06/25 12:27, 20F

06/25 12:28, , 21F
寫成註解有甚麼意義嗎 ?
06/25 12:28, 21F

06/25 12:30, , 22F
因為我只想讓使用者知道有什麼function可以用 但是我不
06/25 12:30, 22F

06/25 12:30, , 23F
想讓他知道其他在實作上的任何相關內容 所以才不想放
06/25 12:30, 23F

06/25 12:30, , 24F
額外的檔案出去QQ
06/25 12:30, 24F

06/25 12:31, , 25F
A.h 不是只有共用的 struct 嗎 ?
06/25 12:31, 25F

06/25 12:31, , 26F
還是你連 struct 內部有甚麼成員都不想讓別人知道 ?
06/25 12:31, 26F

06/25 12:31, , 27F
阿不好意思 我把A.h跟IO.h搞混了 照你的意思就是把
06/25 12:31, 27F

06/25 12:32, , 28F
共用的struct放A.h裡面 最後把A.h跟MyDll.h都丟給使用
06/25 12:32, 28F

06/25 12:32, , 29F
我以為之前那篇就是這意思 XD
06/25 12:32, 29F

06/25 12:32, , 30F
者 然後MyDll.h裡面include A.h這樣對吧?
06/25 12:32, 30F

06/25 12:33, , 31F
上一篇你回的我有看懂啦 只是剛剛一時之間沒切換過來
06/25 12:33, 31F

06/25 12:33, , 32F
然後你還需要看一下這篇了解一下 dllimport 跟 dllexport
06/25 12:33, 32F

06/25 12:37, , 33F
了解 不過IO_API加在struct上的用意其實我不是很了解QQ
06/25 12:37, 33F

06/25 12:37, , 34F
那你先研究一下 DLL 是怎麼運作的.
06/25 12:37, 34F

06/25 12:41, , 35F
了解 目前也只是寫出可以用的 但是運作還不是很熟悉
06/25 12:41, 35F

06/25 12:42, , 36F
整個是被公司趕鴨子上架要做出成品Orz
06/25 12:42, 36F

06/25 12:43, , 37F
不要被煮熟就好~
06/25 12:43, 37F

06/25 12:58, , 38F
會繼續努力研究 有問題再來勞煩大家了!!
06/25 12:58, 38F

06/25 15:08, , 39F
額 原來我又跑題了 orz
06/25 15:08, 39F

06/25 15:15, , 40F
E大 不會啦 你剛好提到一個我沒有注意過的 我會研究
06/25 15:15, 40F

06/25 15:15, , 41F
研究看這中間的差別是什麼
06/25 15:15, 41F

06/25 15:40, , 42F
其實還有一個方法是用 opaque pointer,DLL 只提供一個
06/25 15:40, 42F

06/25 15:41, , 43F
READDATA * 宣告, 然後提供 function 讀寫所有欄位內容
06/25 15:41, 43F

06/25 15:41, , 44F
這樣 DLL 使用者就根本不需要知道 struct 內容了
06/25 15:41, 44F
文章代碼(AID): #1LYkGLgI (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1LYkGLgI (C_and_CPP)