编译环境 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)