IDL与VC混合编程

编译环境 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)
原文地址:https://www.cnblogs.com/lartely/p/2014481.html