Handling Arrays Between ASP and COM

原创 2002年03月09日 17:56:00
Handling Arrays Between ASP and COM
By Adam B. Richman
Rating: 3.4 out of 5
Rate this article


print this article

email this article to a colleague

Introduction
As Visual Basic (VB) components become more and more pervasive on the Web application development landscape, we are forced to code with more structure in this environment than ever before. No longer is the slick code for our webs restricted to our webs; business objects have made short work of distributing these solutions. We have to plan for this use.

Realizing all shops and projects are different, I don抰 believe that I have made a database call from within ASP since summer ?998, so understand that I am coming from a component-driven Web perspective. Furthermore, I can抰 remember the last time a client has asked me to create a static HTML page. The majority of what we do is dynamic. Sometimes, I find myself calling 411 and asking for Number where Last Name = 慡mith?and First Name like 慗o%?

One strategy for improving the structure of our Web development involves the way we pass data between ASP and components. I will usually try to group items (such as rights) together with the user they apply to and pass them in a variant array between components and/or back to ASP. In this way I can pass data from record sets (using the getRows method of ADODB.Recordset) and database updates to COM as well as my grouped rights all in the same type (structure) of variable. This is a question of 揺ase of use.? You may prefer to return record sets to ASP as themselves. My rationale is that I will definitely use arrays to pass and manipulate data within ASP and VB, so I抎 rather pass my record sets that way as well. Chalk it up to personal preference.

The Problem
My recent discovery of a bug or a design limitation between VB and ASP relates to how VB and ASP interpret arrays. I rely heavily on arrays, therefore a utility component is one of the first I create. One of the most essential functions in that component is my ConvertToArray function. This is an asset when writing Web apps using ActiveX components.

To quickly build components and save myself from breaking interfaces*, I like to use arrays to pass data back and forth between components. At times I also use this technique to pass data from ASP to COM. Below are two code snippets. Looking at Snippet 1, I am constructing a simple two-dimensional array (in this case it didn抰 need to be two-dimensional).

Snippet 1: Create an ASP called testCase.asp, and run it.




If you construct and parse this variant array in VB Script, it will work as intended. If you construct and parse this variant array in VB, it will work as intended as well. However, if you wish to pass your array "by value" (ByVal) from ASP to VB, you will see some messy results. Whether by design or mistake, when you pass a Variant array from ASP to COM ByVal, VB will throw an Automation Exception, and that is the problem. Also, don抰 run Snippet 2 (below) in any VB component you have created before saving your data or you will have to kill it via the Task Manager.

Create an ActiveX component called TestCases.dll and a class called ArrayFailure.

Snippet 2:




Now, of course, you could pass the variant array "by reference" (ByRef), but there抯 a catch.** It wouldn抰 matter much if these weren抰 shared business objects. Yes, I could take the responsibility of always preserving the data in an object passed ByRef which was intended to be passed and not manipulated, but this seems overly involved and it is not my preference.
The Solution
There抯 a COM solution for a COM problem. Create a function that will parse a string and return an array from VB. ASP preserves the returned variant array and it will not cause an Automation Exception when sent into a component ByVal. To do this, replace the ASP-built array in Snippet 1 with the sample code in Snippet 3.

Add this snippet to the above ASP sample in place of the ASP-built array.

Snippet 3




Note: You will not need to dimension the bounds of this array (see above code appearing in bold) in ASP. VB will do that inside your ConvertToArray function.

Create an ActiveX component and class to house useful utilities.

Snippet 4:




Snippet 4 contains a function and sub to take a string and parse it out, then throw it into an array. This is not the best way to do this. You will find various opinions that say Do抯 are faster than For抯 or parsing strings is faster than calling ReDim and Preserve methods. This sample is simple. It doesn抰 take up much space and it was quick to write You probably have your own techniques for doing this, and they will work fine or better.

The main point is that you have your data in an array that will work for your needs in both ASP and VB. There are a couple of things to remember when you are creating this sort of array builder. If you are going to use a .getRows method for data retrieval in COM, you will notice that it populates arrays by indexing on the outer element. Also remember that if you plan on resizing arrays in VB sent in as a parameter by ASP, you will need to ReDim Preserve the array. VB will only allow you to resize the outer element of your array (e.g., vntArray(1,10) can only be resized by (1,n). The 1 in this example is fixed).

Additional Ideas
There are various ways to profit from using arrays in building COM/ASP solutions. One of the most valuable is the ability to change the ways your functions behave without touching the functions?parameters. From my vantage point, everywhere there is a database update, I can use a variant array as a parameter and never break binary compatibility***, while continually cramming more and more updates in the function as the scope or requirements change. Example of a Modify function that implements a variant array. Snippet 5



Snippet 5 is an example of a very generic function called "Modify" that I can use to change anywhere from one to 10 (or more) columns in a table passed in by strTableName. For this to be a truly effective COM object, it would contain the business logic, instead of the ASP that calls it. Look at this function as being incomplete. A more complete version would take in parameters that we would perform business operations upon and then some (potentially a growing number) additional parameters would be sent in by vntModifications.

Keeping in mind generic nature of the example, if the case demanded that I need more criteria (the where statement in this snippet) to make my update, I would need to define that in the design stage and include that in my parameter list. For the sake of simplicity, consider the above example to be updating a table with a unique index Item_Num. We could construct myriad different arrays containing a name/value pair with which we wish to update the record. Of course, we could use a string for input. We could continue to grow the string and never break the interface as well. If we know that the input will never need massaging, this will work fine. On the other hand, if we may need to massage data, it is far simpler to test elements of an array than parse a string (see Snippet 6). This is an example of the ease of testing a condition in an array vs. parsing a string. Snippet 6




Whether you are using strings or arrays, adding some structure to your code will greatly benefit future modifications. We are forced to code with more structure than ever before, and seeing the potential pitfalls should allow us to create a more pliant and robust application.
Notes
* Use arrays for input parameters wherever logical. Arrays can greatly reduce the number of interface changes made. By constructing functions with arrays as parameters, components can service many more component calls without interface changes.

** Declare all function parameters explicitly ByVal ("A way of passing the value, rather than the address, of an argument to a procedure. This allows the procedure to access a copy of the variable. As a result, the variable's actual value can't be changed by the procedure to which it is passed." MSDN Visual Studio 6.0) except those intended to return a value ByRef. This will prevent changing the values of data that may be used later in code, be that ASP or other components.

*** Always compile components using binary compatibility (see Design Note below). This will enable others calling these objects to declare their components using vTable Binding (Early Binding) and to not need to recompile every time internal code is changed. According to MSDN; "For in-process components, vtable binding reduces call overhead to a tiny fraction of that required for DispID binding." VB generates a GUID for components in the Windows Registry. When you compile with binary compatibility, VB will use the previous GUID for its registry entry, provided the interface has not changed. Consequently, customers will never need to recompile their objects when we recompile our component., (This is only pertinent to "component-to-component" design. This will have no effect on ASP because all ASP is late bound.) Although it would be very convenient to create one giant ActiveX component with all of your classes, I wouldn抰 advise it. By doing this you greatly increase the number of times you will have to change interfaces, thus breaking binary compatibility. Creating this large ActiveX component is fine if you are creating specific classes that will not be shared business objects ?others aren抰 relying on your GUID. I try to group my classes in their functionality (relationships), but any type of grouping will work. Note: Be mindful of cross dependencies that can make build time a nightmare.

Design Note on Planning the Use of Binary Compatibility
* Use arrays for input parameters wherever logical. Arrays can greatly reduce the number of interface changes made. By constructing functions with arrays as parameters, components can service many more component calls without interface changes.

** Declare all function parameters explicitly ByVal ("A way of passing the value, rather than the address, of an argument to a procedure. This allows the procedure to access a copy of the variable. As a result, the variable's actual value can't be changed by the procedure to which it is passed." MSDN Visual Studio 6.0) except those intended to return a value ByRef. This will prevent changing the values of data that may be used later in code, be that ASP or other components.

*** Always compile components using binary compatibility (see Design Note below). This will enable others calling these objects to declare their components using vTable Binding (Early Binding) and to not need to recompile every time internal code is changed. According to MSDN; "For in-process components, vtable binding reduces call overhead to a tiny fraction of that required for DispID binding." VB generates a GUID for components in the Windows Registry. When you compile with binary compatibility, VB will use the previous GUID for its registry entry, provided the interface has not changed. Consequently, customers will never need to recompile their objects when we recompile our component., (This is only pertinent to "component-to-component" design. This will have no effect on ASP because all ASP is late bound.) Although it would be very convenient to create one giant ActiveX component with all of your classes, I wouldn抰 advise it. By doing this you greatly increase the number of times you will have to change interfaces, thus breaking binary compatibility. Creating this large ActiveX component is fine if you are creating specific classes that will not be shared business objects ?others aren抰 relying on your GUID. I try to group my classes in their functionality (relationships), but any type of grouping will work. Note: Be mindful of cross dependencies that can make build time a nightmare.

Download the Code
You can download the complete source for the sample contained in this article:

http://15seconds.com/files/990826.zip

About the Author
A Russian interpreter by education, Adam Richman has been a web developer since 1995. He is currently a consultant on a 3-tier development project at a pharmaceutical firm in Research Triangle Park, North Carolina. Adam is also working to establish a project-oriented web development business implementing COM, Java, VB and ASP solutions. He can be contacted at arichman@ipsolve.com.

asp调用DLL或com组件的简述及网上摘例

动态联接库(DLL)是加快应用程序关键部分的执行速度的重要方法 asp调用DLL或com组件的方法:步骤一: 装载 METADATA 标签中指定的类型库。 Path是mydll.dll在机器上存放的路...
  • gkq8124372
  • gkq8124372
  • 2009年04月23日 15:43
  • 4009

EJB3方法调用的错误及其处理

在WildFly AS 10上部署EJB服务,在Eclispe中运行单元测试,遇到如下错误: java.lang.NoSuchMethodError: org.jboss.logging.Logg...
  • taiyangdao
  • taiyangdao
  • 2016年03月07日 16:34
  • 1369

写COM组件用于ASP/PHP等动态网页

ASP、PHP等动态网页语言的功能已很强大,但COM能使它如虎添翼。其实我们平时用的ADO、FSO、Jmail等也就是COM。借助COM,WEB可以调用本地应用程序的几乎所有功能来反馈给页面。例如,查...
  • asanscape
  • asanscape
  • 2014年04月12日 12:34
  • 2110

C#创建COM组件,并在ASP、PHP中调用方法

1、新建项目        -- 选择Visual C# - 类库        -- 项目名称:如 SendMailLib        -- 去掉选中项 ”为解决方案创建目录”        --...
  • xmlife
  • xmlife
  • 2016年06月11日 10:44
  • 1157

ASP.NET调用COM

在VC++z中利用ATL COM AppWizard写一个COM组件。   在VS.NET中利用“型别库导入工具”(TlbImp.exe),从COM组件的型别库生成一个装配件,这样受控代码就能通过访问...
  • tohigh
  • tohigh
  • 2004年06月26日 14:37
  • 4586

Windows - "The trust relationship between this workstation and the primary domain failed"

Problem Seen on Windows clients in a domain environment. What's Happened? Put simply, ...
  • killer000777
  • killer000777
  • 2012年06月06日 15:58
  • 10741

Pass Arrays Between vc++ and vb

 SUMMARY This article discusses some aspects related to passing data in arrays between Microsoft Vis...
  • hujiangnet
  • hujiangnet
  • 2008年11月01日 16:21
  • 588

java中Arrays类的用法

java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的。具有以下功能: ² 给数组赋值:通过fill方法。 ² 对数组排序:通过sort方法,按升序。 ² 比较数组:通过...
  • object_allen
  • object_allen
  • 2014年12月03日 12:15
  • 8781

asp查询 between and 写法

select   *   from   [表名]   where   字段名   between   1   and   2    1--2之间必须是数字...
  • yingzi0011
  • yingzi0011
  • 2008年10月16日 12:42
  • 214

Alignment trap的问题

在arm linux下,碰到如下错误。百度了一下,you Alignment trap: not handling instruction e1923f9f at []...
  • Dable_cn
  • Dable_cn
  • 2014年05月06日 10:24
  • 4023
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Handling Arrays Between ASP and COM
举报原因:
原因补充:

(最多只允许输入30个字)