编译环境 VC6.0 + IDL8.0
1 在vc中调用IDL
使用动态链接库(DLL)和使用ActiveX
1.1 使用动态链接库在vs中调用idl
vc编译环境设置,打开ToolsOptions在Show directies for 选择Libraray files 添加路径<IDL>\bin\bin.x86.在Include files添加路径<IDL>\external.打开ProjectSettings,选中link属性页在Object/library modules添加idl.lib
#include "stdafx.h" #include "IDL_VC.h" #include "export.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object CWinApp theApp; using namespace std; void free_cb(UCHAR *a) { free (a); } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else { // TODO: code your application's behavior here. HANDLE hInstance=AfxGetInstanceHandle(); IDL_Win32Init(0,hInstance,NULL,0); float *a=(float *) calloc(8,sizeof(float)); for (int i=0;i<8;i++) { a[i]=i; } IDL_MEMINT dim[]={2,4}; IDL_ImportNamedArray("namea",2,dim,IDL_TYP_FLOAT, (UCHAR *)a,free_cb,0); IDL_ExecuteStr("plot,namea"); IDL_Cleanup(TRUE); } return nRetCode; }
显示为plot,a
1.2 使用ActiveX在vs中调用idl
在vs建立支持ActiveX的工程,添加ActiveX控件IDLDrawWidget通过类向导在Dlg中添加CIDLDrawX3类m_idl.
BOOL CIDLActiveDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_idl.InitIDL((long)m_hWnd); m_idl.CreateDrawWidget(); float *a=(float *)calloc(8,sizeof(float)); int i; SAFEARRAYBOUND rgsabound[1]; for (i=0;i<8;i++) { a[i]=(float)i; } rgsabound[0].lLbound=0; rgsabound[0].cElements=8; SAFEARRAY *psa=SafeArrayCreate(VT_R4,1,rgsabound); psa->pvData=a; VARIANT aa; VariantInit(&aa); aa.vt=VT_ARRAY|VT_R4; aa.parray=psa; m_idl.SetNamedArray("aaa",aa,0); m_idl.ExecuteStr("plot,aaa"); return TRUE; // return TRUE unless you set the focus to a control }
2 在IDL中调用C
2.1 使用Call_External实现
PRO IDLToVCStructAStructure__define
s = { IDLToVCStructAStructure,zero:0B, one:0L, two:0.0, three:0.0D, four:[0,0] }
END
function IDLToVCStructGetLib
common GET_EXLIB_BLK, IDLToVCStructShLib
; 测试共享库是否存在。若存在直接调用;否则创建
;LibPath=IDLToVCStructShLib
build_lib = n_elements(IDLToVCStructShLib) eq 0
if (not build_lib) then build_lib = not FILE_TEST(IDLToVCStructShLib, /READ)
if (build_lib) then begin
; 定位CALL_EXTERNAL调用C函数所在的目录
call_ex_dir='D:\Program Files\ITT\IDL\IDL80\' & source = [ 'IDLToVCStruct' ]
export_rtns=[ 'IDLToVCStructNatural', 'IDLToVCStruct']
; 创建动态连接库的目录
FILE_MKDIR, 'D:\Program Files\ITT\IDL\IDL80\IDLToVCStructDLL'
!MAKE_DLL.COMPILE_DIRECTORY='D:\Program Files\ITT\IDL\IDL80\IDLToVCStructDLL'
; 编译C语言函数,创建动态连接库
MAKE_DLL, source, 'IDLToVCStructDLLLib', export_rtns, $
INPUT_DIR=call_ex_dir, DLL_PATH=IDLToVCStructShLib
endif
return, 1
end
PRO IDLToVCStruct, s_arr
; 检查s_arr的数据类型是否为结构类型
common GET_EXLIB_BLK, IDLToVCStructShLib
CASE SIZE(s_arr, /TYPE) OF
0 : s_arr = replicate({IDLToVCStructAStructure},3)
8 : IF TAG_NAMES(s_arr,/STRUCTURE_NAME) NE $
'IDLToVCStructAStructure' THEN MESSAGE,'structure type error'
ELSE: MESSAGE, 'S_ARR must be a structure'
ENDCASE
N = N_ELEMENTS(s_arr)
PRINT, s_arr; 输出调用前数据
func = 'IDLToVCStruct'
print,IDLToVCStructGetLib()
Result = CALL_EXTERNAL(IDLToVCStructShLib, func, s_arr, n, VALUE=[0,1], /CDECL)
PRINT, s_arr; 输出调用后数据
END
#include "idl_export.h" typedef struct { unsigned char zero; IDL_LONG one; float two; double three; short four[2]; } ASTRUCTURE; int IDLToVCStructNatural(ASTRUCTURE *mystructure, IDL_LONG n) { for (; n--; mystructure++) { mystructure->zero+=20; mystructure->one+=20; mystructure->two+=20; mystructure->three+=20; mystructure->four[0]+=20; mystructure->four[1]+=20; } return 1; } int IDLToVCStruct(int argc, void *argv[]) { if (argc != 2) return 0; return IDLToVCStructNatural((ASTRUCTURE*) argv[0], (IDL_LONG) argv[1]); }
2.2 使用LINKIMAGE实现
// VcDll.h : 定义 DLL 应用程序的入口点。 #include "export.h" #pragma comment(lib, "idl.lib") extern "C" _declspec(dllexport) IDL_VPTR mult2(int argc, IDL_VPTR argv[]); // VcDll.cpp : 定义 DLL 应用程序的入口点。 // #include "stdafx.h" #include "export.h" #include "VcDll.h" #pragma comment(lib, "idl.lib") extern "C" _declspec(dllexport) IDL_VPTR mult2(int argc, IDL_VPTR argv[]) { IDL_VPTR src; src=argv[0]; IDL_ENSURE_SCALAR(src); src=IDL_CvtFlt(1,argv); src->value.f=src->value.f*2; return(src); }
THEN RUN IDL LINKIMAGE,'mult2','vcdll',/funct print,mult2(3)