討論區快速選單
知識庫快速選單
網路投保旅行平安險 掌握Salesforce雲端管理秘訣
[ 回上頁 ] [ 討論區發言規則 ]
C# DLL問題
更改我的閱讀文章字型大小
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/11 下午 03:18:48
1.我有2個DLL檔案,檔名和函式名稱都ㄧ樣,除了函式內容不ㄧ樣,只是一個使用C++6.0包成的DLL,另一個使用C#包成的DLL。我的系統是使用C#完成的。

我加入C#包成的DLL只需要使用->加入參考既可以使用了。
我加入C++6.0包成的DLL需要使用->DllImport才可以使用了。

系統程式是固定的,DLL會變化,我要如何統一作法,可以載入各式不同語法包成的DLL檔案。

假設系統內容如下:
1.C#_DLL

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using "test"
namespace ConsoleApplication3
{
    class Program
    {
     static void Main(string[] args)
     {
     test.class1 aa=new class1(); //C#_DLL

     int a = 2;
     int b = 11;
     int c=aa.Max(a, b); //比較大小會回傳11

     Console.Write("C={0}", c);
     Console.ReadLine();
     }
    }
}

2.c++_DLL

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
    class Program
    {
     [DllImport(@"test.dll")]
     static extern int Max(int a, int b);//c++_DLL

     static void Main(string[] args)
     {

     int a = 2;
     int b = 11;

     int c=Max(a, b); //比較大小會回傳11

     Console.Write("C={0}", c);
     Console.ReadLine();
     }
    }
}
作者 : sleepyfish(愛睏魚) C#優秀好手C++優秀好手貼文超過500則
[ 貼文 524 | 人氣 0 | 評價 2890 | 評價/貼文 5.52 | 送出評價 13 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/11 下午 03:43:46
將 Native Win32 API wrap 成 CLR 的形式:

public class1 {
     [DllImport(@"test.dll", EntryPoint="Max")]
     private static extern int Native_Max(int a, int b);//c++_DLL

     public class1() {}

     public int Max(int a, int b)
     {
     return Native_Max(a, b);
     }
}
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/11 下午 03:55:06
各位大大
我的DLL為因為使用者不同而有所改變,為什麼要把DLL檔案名子取一樣,是因為系統已建構呼叫的方式。
C#與C++裡面都有Max()函式,我希望底下程式能共用C#與C++的DLL,只要換test.DLL的版本。有什麼作法可以
只換test.DLL版本程式碼都可以共用

例如:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using "test" <-------------------------C#_DLL可以改變成其他的版本DLL,程式都不改變
namespace ConsoleApplication3
{
    class Program
    {
     static void Main(string[] args)
     {
     test.class1 aa=new class1(); //C#_DLL

     int a = 2;
     int b = 11;
     int c=aa.Max(a, b); //比較大小會回傳11

     Console.Write("C={0}", c);
     Console.ReadLine();
     }
    }
}
作者 : marlon(marlon) C#卓越專家貼文超過200則
[ 貼文 495 | 人氣 1886 | 評價 3510 | 評價/貼文 7.09 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/13 下午 01:42:31
>我加入C#包成的DLL只需要使用->加入參考既可以使用了。
>我加入C++6.0包成的DLL需要使用->DllImport才可以使用了。
這二種方式都會讓程式與 dll 綁死, 想要做到抽換組件就必須加轉接頭, 以動態載入
轉接程式1 => 把 C# DLL 加入參考
轉接程式2 => DllImport C++ DLL
二隻轉接程式所有命名一樣, 程式改成
Assembly asm = Assembly.Load(轉接程式檔案路徑);
Type type = asm.GetType(轉接程式類別全名);
type.GetMethod(函式名稱).Invoke() 執行函式
把轉接程式連同對應的 dll 一起給客戶即可
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/13 下午 03:49:20
謝謝大大賜教,我試試看^^
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/13 下午 03:49:25
謝謝大大賜教,我試試看^^
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/13 下午 06:53:26
marlon大大
我還是做不出來因為文章中有些東西不是很懂
例如:
轉接程式1 => 把 C# DLL 加入參考 <---C#程式1--做成EXE檔案還是做成DLL
轉接程式2 => DllImport C++ DLL <---C#程式1--做成EXE檔案還是做成DLL
二隻轉接程式所有命名一樣, 程式改成
Assembly asm = Assembly.Load(轉接程式檔案路徑);
Type type = asm.GetType(轉接程式類別全名);
type.GetMethod(函式名稱).Invoke() 執行函式
把轉接程式連同對應的 dll 一起給客戶即可
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/13 下午 06:55:16
marlon大大
我還是做不出來因為文章中有些東西不是很懂
例如:
轉接程式1 => 把 C# DLL 加入參考 <---C#程式1--做成EXE檔案還是做成DLL
轉接程式2 => DllImport C++ DLL <---C#程式2--做成EXE檔案還是做成DLL
二隻轉接程式所有命名一樣, 程式改成
Assembly asm = Assembly.Load(轉接程式檔案路徑); <---轉接程式檔案路徑是抓哪一個檔案
Type type = asm.GetType(轉接程式類別全名);
type.GetMethod(函式名稱).Invoke() 執行函式
把轉接程式連同對應的 dll 一起給客戶即可


可以請大大做個範例程式嗎?
作者 : marlon(marlon) C#卓越專家貼文超過200則
[ 貼文 495 | 人氣 1886 | 評價 3510 | 評價/貼文 7.09 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人y2kmomo註記此篇回應為最佳解答 2010/5/14 上午 11:22:35
程式部署
\bin\主程式.exe
for c#
\bin\cslib\funLib.dll (c#轉接程式)
\bin\cslib\test.dll (c#版)
for c++
\bin\cpplib\funLib.dll (c++轉接程式)
\bin\cpplib\test.dll (c++版)
執行時看用那一版本要把子目錄的檔案 copy 到 exe 檔路徑, 也就是主程式.exe + funLib.dll + test.dll 一定要同路徑, 否則 .Net 無法自動找到檔案, 得自行解析組件

c#轉接程式 \bin\cslib\funLib.dll
namespace Demo
{
    public static class FunLib
    {
     public static int Max(int a, int b) { return aa.Max(a, b); }
    }
}

C++轉接程式 \bin\cpplib\funLib.dll
namespace Demo
{
    public static class FunLib
    {
     [DllImport(@"test.dll")]
     public static extern int Max(int a, int b);//c++_DLL
    }
}

二個版本都叫 funLib.dll, 類別全名都是 Demo.FunLib, 函式名稱都是 Max

程式
拿掉 using "test" 加 using System.Reflection;
namespace ConsoleApplication3
{
    class Program
    {
     static void Main(string[] args)
     {
     int a = 2;
     int b = 11;
     Assembly asm = Assembly.Load("funLib");
     Type funType = asm.GetType("Demo.FunLib");
     int c = (int)funType.GetMethod("Max", BindingFlags.Public | BindingFlags.Static).Invoke(null, new object[] { a, b });
     Console.Write("C={0}", c);
     Console.ReadLine();
     }
    }
}
作者 : y2kmomo(毛毛)
[ 貼文 8 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/5/17 上午 09:41:18
謝謝marlon大大
我已成功做出範例~~由衷感謝
 板主 : 小朱
 > C# - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C# - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C#
1 小朱 6270 
2 蹂躪 2700 
3 HKLN.net 2440 
4 marlon 2130 
5 joe 1320 
6 識丁 910 
7 好說 860 
8 愛睏魚 770 
9 總幹事 720 
10 Demonbane 600 
C#
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.09375