主页 > 编程资料 > C# >
发布时间:2015-09-26 作者:网络 阅读:231次

                 我想从Oracle的存储过程通过一个外部dll(Delphi编写)去访问C#写的WebService时,出现了“尚未调用 CoInitialize”
不知道是怎么回事,望各位指点一二。
1、我在Oracle里写了一个函数AddNumber如下:
CREATE OR REPLACE  FUNCTION "MY"."ADD"  (a in BINARY_INTEGER,b
   in BINARY_INTEGER) RETURN BINARY_INTEGER AS
EXTERNAL LIBRARY MY_LIB
NAME "AddNumber"
LANGUAGE C;
2、写了一个过程AddTest如下:
CREATE OR REPLACE  PROCEDURE "MY"."ADDTEST"   (a in
   BINARY_INTEGER,b in BINARY_INTEGER)
as
retVal BINARY_INTEGER;
begin
retVal:=Add(a,b);
end;
3、创建了MY_LIB包:
CREATE OR REPLACE  LIBRARY MY_LIB AS 'C:\oracle\ora92\bin\MyWebservice.dll';
4、在Delphi里创建了一个MyWebservice.dll,并拷贝其到$ORACLE_HOME$\BIN目录下,其中有一个方法:
interface
function AddNumber(a:integer;b:integer):Integer;cdecl;
....
implementation
procedure DoGetWebServiceErr(ErrMsg:string);
var
  logFile: TextFile;
  i:integer;
begin
   AssignFile(logFile,'d:\test.txt');
  try
   Rewrite(logFile);    
  Write(logFile,ErrMsg);
  finally
   CloseFile(logFile);
  end;
end;
function AddNumber(a:integer;b:integer):Integer;
begin
   try
     Result := GetMyWebServiceSoap().AddNumber(a,b);
  except
  on E: Exception do DoGetWebServiceErr(E. E.Message);
  else
    Result :=-1;
  end;
end;
.....
其中:GetMyWebServiceSoap()是我用WSDL Importer导入生成的MyWebService.pas中的一个方法。
我在该Dll的项目文件里导出了该方法:
exports
AddNumber;
5、用C#在Localhost创建了一个名为MyWebService的Web Service,其中有一个名为AddNumber的WEB方法,其定义如下:
[WebMethod]
public int AddNumber(int a,int b)
{
 return a+b;
}
6、我用c#写了一个Windows Form客户端,通过调用上面用Delphi 写的dll,测试该Web方法,测试成功
[DllImport(DLLPath,EntryPoint = "MyWebservice.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private extern static int AddNumber(int a,int b);
......
///测试按钮
private void buttonTestWebService_Click(object sender, System.EventArgs e)
{
Consle.Write( AddNumber(1,2));
}
7、在SQL*Plus里测试失败,打开Test.txt文件内容为“尚未调用 CoInitialize”,测试代码如下
EXECUTE Addtest(1,1);
如果将Delphi中的AddNumber 修改为
function AddNumber(a:integer;b:integer):Integer;
begin
   try
     Result :=a+b;//不调用WebService,直接计算
  except
  on E: Exception do DoGetWebServiceErr(E. E.Message);
  else
    Result :=-1;
  end;
end;
执行则成功。
Oracle的Listener.ora和tnsnames.ora的配置如下
# LISTENER.ORA Network Configuration File: C:\oracle\ora92\network\admin\listener.ora
# Generated by Oracle configuration tools.
MY_EXTPROC_LISTENER =

(ADDRESS_LIST =
 (ADDRESS= (PROTOCOL=ipc)
    (KEY = extproc)
 )
)
SID_LIST_MY_EXTPROC_LISTENER =
(SID_LIST =
 (SID_DESC =
 (SID_NAME = extproc)
 (ORACLE_HOME =  C:\oracle\ora92)
 (PROGRAM= C:\oracle\ora92\bin\extproc)
 (ENVS="EXTPROC_DLLS=ANY")
 )
)
# TNSNAMES.ORA Network Configuration File: C:\oracle\ora92\network\admin\tnsnames.ora
# Generated by Oracle configuration tools.

EXTPROC_CONNECTION_DATA.WORLD =
 (DESCRIPTION =
   (ADDRESS = (PROTOCOL = IPC)(KEY = extproc))
   (CONNECT_DATA =
     (SID = extproc)
   )
 )

关键字词: