首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

跨語言復用:用 Delphi 為 Visual C++ 添加 JPEG 處理功能

     編輯:Delphi

Visual C++ 歷來對 JPEG 等常見圖形格式支援不足,而 Delphi/C++ Builder 內建強大的 TJPEGImage 類別。本文展示如何將 Delphi 的 JPEG 功能封裝為 DLL,供 VC++ 呼叫,實現「幾分鐘內讓 VC++ 用上 JPEG」的 DIY 方案。

方案架構

  • Delphi 端:建立 DLL 專案,匯出 4 個函數(建立/載入/釋放/繪製 JPEG)
  • VC++ 端:LoadLibrary 載入 DLL,GetProcAddress 取得函數指標,封裝為 C++ 類別使用
  • 優勢:無需註冊 ActiveX、無 MFC 靜態連結限制、原生效能、程式碼極簡

Delphi DLL 完整代碼

專案檔 (ImageLib.dpr)

library ImageLib;
uses SysUtils, Classes, MainFn in 'MainFn.pas';
exports
  CreateJPEGImage, LoadJPEGImage, FreeJPEGImage, DrawJPEGImage;
begin end.

實作單元 (MainFn.pas)

unit MainFn;
interface
uses SysUtils, Classes, Windows, Graphics, JPEG;
function CreateJPEGImage: TJPEGImage; stdcall; export;
function LoadJPEGImage(image: TJPEGImage; szFileName: PChar): LongBool; stdcall; export;
procedure FreeJPEGImage(image: TJPEGImage); stdcall; export;
procedure DrawJPEGImage(hdc: HDC; x, y: Integer; image: TJPEGImage); stdcall; export;
implementation

function CreateJPEGImage: TJPEGImage;
var img: TJPEGImage;
begin
  try img := TJPEGImage.Create; Result := img; except Result := nil; end;
end;

function LoadJPEGImage(image: TJPEGImage; szFileName: PChar): LongBool;
var fn: string;
begin
  try fn := StrPas(szFileName); image.LoadFromFile(fn); Result := True; except Result := False; end;
end;

procedure FreeJPEGImage(image: TJPEGImage);
begin image.Free; end;

procedure DrawJPEGImage(hdc: HDC; x, y: Integer; image: TJPEGImage);
var Canvas: TCanvas;
begin
  Canvas := TCanvas.Create;
  try Canvas.Handle := hdc; Canvas.Draw(x, y, image); finally Canvas.Free; end;
end;
end.

VC++ 使用範例 (Dialog Based 專案)

typedef void* PJPEG; // 不透明指標對應 TJPEGImage

typedef PJPEG (__stdcall* CREATEJPEGIMAGE)();
typedef BOOL (__stdcall* LOADJPEGIMAGE)(PJPEG, LPCSTR);
typedef void (__stdcall* FREEJPEGIMAGE)(PJPEG);
typedef void (__stdcall* DRAWJPEGIMAGE)(HDC, int, int, PJPEG);

class CTDlg : public CDialog {
  HINSTANCE m_hLib;
  CREATEJPEGIMAGE pCreateJPEGImage;
  LOADJPEGIMAGE pLoadJPEGImage;
  FREEJPEGIMAGE pFreeJPEGImage;
  DRAWJPEGIMAGE pDrawJPEGImage;
public:
  BOOL OnInitDialog() {
    m_hLib = LoadLibrary("ImageLib.dll");
    pCreateJPEGImage = (CREATEJPEGIMAGE)GetProcAddress(m_hLib, "CreateJPEGImage");
    pLoadJPEGImage = (LOADJPEGIMAGE)GetProcAddress(m_hLib, "LoadJPEGImage");
    pFreeJPEGImage = (FREEJPEGIMAGE)GetProcAddress(m_hLib, "FreeJPEGImage");
    pDrawJPEGImage = (DRAWJPEGIMAGE)GetProcAddress(m_hLib, "DrawJPEGImage");
  }
  void OnDestroy() { if (m_hLib) FreeLibrary(m_hLib); }
  void OnPaint() {
    CPaintDC dc(this);
    PJPEG pJPEG = (*pCreateJPEGImage)();
    if (pJPEG) {
      if ((*pLoadJPEGImage)(pJPEG, "c:\\test.jpg"))
        (*pDrawJPEGImage)(dc.m_hDC, 0, 0, pJPEG);
      (*pFreeJPEGImage)(pJPEG);
    }
  }
};

關鍵技術點

  • stdcall 呼叫慣例:確保 Delphi 與 VC++ 二進制相容
  • 不透明指標:VC++ 端用 void* 對應 Delphi 物件實例,不需知道內部結構
  • TCanvas.Handle 指派:將 Win32 HDC 包裝為 VCL Canvas 繪圖
  • 例外安全:Delphi 端全部用 try-except 包裹,轉為 BOOL 回傳,避免跨語言例外崩潰

擴展建議

  • 新增 SaveJPEGImage、GetJPEGDimensions、SetJPEGQuality 等功能
  • 封裝為 VC++ 端的 CJPEGImage RAII 類別,自動管理生命週期
  • 支援記憶體流 (TMemoryStream) 避免臨時檔案
  • 同理可封裝 PNG、GIF、BMP 等格式,構建通用影像 DLL

此法同樣適用於 C++Builder、Free Pascal、Lazarus 等支援 stdcall DLL 匯出的語言,實現跨語言的圖形功能復用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved