使用 Java 访问服务
[从 Windows 7 开始,Microsoft 代理已弃用,可能在后续版本的 Windows 中不可用。]
还可以从 Java 小程序访问 Microsoft 代理服务。 许多可通过 Microsoft 代理接口访问的函数通过引用传递的参数返回值。 若要从 Java 传递这些参数,必须在代码中创建单元素数组,并将其作为参数传递给相应的函数。 如果使用 Microsoft Visual J++ 并在 Microsoft 代理服务器上运行 Java 类型库向导,请参阅 summary.txt 文件以查看哪些函数需要数组参数。 过程类似于 C 中的过程;使用 IAgentEx 接口创建服务器的实例,然后加载字符:
private IAgentEx m_AgentEx = null;
private IAgentCharacterEx m_Merlin[] = {null};
private int m_MerlinID[] = {-1};
private int m_RequestID[] = {0};
private final String m_CharacterPath = "merlin.acs";
public void start()
{
// Start the Microsoft Agent Server
m_AgentEx = (IAgentEx) new AgentServer();
try
{
Variant characterPath = new Variant();
characterPath.putString(m_CharacterPath);
// Load the character
m_AgentEx.Load(characterPath,
m_MerlinID,
m_RequestID);
}
从 HTTP 远程位置(如网站)加载字符时,过程略有不同。 在这种情况下, Load 方法是异步的,将引发 COM 异常E_PENDING (0x8000000a) 。 需要捕获此异常并正确处理它,如以下函数中所做的那样:
// Constants used in asynchronous character loads
private final int E_PENDING = 0x8000000a;
private final int NOERROR = 0;
// This function loads a character from the specified path.
// It correctly handles the loading of characters from
// remote sites.
// This sample doesn't care about the request id returned
// from the Load call. Real production code might use the
// request id and the RequestComplete callback to check for
// a successful character load before proceeding.
public int LoadCharacter(Variant path, int[] id)
{
int requestid[] = {-1};
int hRes = 0;
try
{
// Load the character
m_AgentEx.Load(path, id, requestid);
}
catch(com.ms.com.ComException e)
{
// Get the HRESULT
hRes = e.getHResult();
// If the error code is E_PENDING, we return NOERROR
if (hRes == E_PENDING)
hRes = NOERROR;
}
return hRes;
}
public void start()
{
if (LoadCharacter(characterPath, m_MerlinID) != NOERROR)
{
stop();
return;
}
// Other initialization code here
.
.
.
}
然后获取可用于访问其方法的 IAgentCharacterEx 接口:
// Get the IAgentCharacterEx interface for the loaded
// character by passing its ID to the Agent server.
m_AgentEx.GetCharacterEx(m_MerlinID[0], m_Merlin);
// Show the character
m_Merlin[0].Show(FALSE, m_RequestID);
// And speak hello
m_Merlin[0].Speak("Hello World!", "", m_RequestID);
同样,若要收到事件通知,必须实现 IAgentNotifySink 或 IAgentNotifySinkEx 接口,创建并注册该类型的对象:
...
// Declare an Agent Notify Sink so that we can get
// notification callbacks from the Agent server.
private AgentNotifySinkEx m_SinkEx = null;
private int m_SinkID[] = {-1};
public void start()
{
...
// Create and register a notify sink
m_SinkEx = new AgentNotifySinkEx();
m_AgentEx.Register(m_SinkEx, m_SinkID);
…
// Give our notify sink access to the character
m_SinkEx.SetCharacter(m_Merlin[0]);
...
}
若要从 Java 小程序访问 Microsoft 代理,必须生成随小程序一起安装的 Java 类。 例如,可以使用 Visual J++ Java 类型库向导来生成这些文件。 如果计划在网页上托管小程序,则需要生成一个签名的 Java CAB,其中包括随页面一起下载的生成的类文件。 访问 Microsoft 代理服务器需要类文件,因为它是在 Java 沙盒外部执行的 COM 对象。