I have an issue with x64 Windows platforms failing to marshal RPC data -
error 1766. At the same time x86 platforms work ok. Changing structure
packing or memory allocation (MIDL or OSF) does not help.
IDL interface:
[
uuid(26bae633-b0b6-4485-9bd1-d29a309ecdff),
version(1.0),
endpoint("ncacn_ip_tcp:[1999]")
]
interface iface
{
typedef struct struct_1 {
unsigned long fields;
} struct_1_t;
typedef struct struct_2
{
error_status_t status;
[unique] struct_1_t *data;
} struct_2_t;
typedef struct struct_3
{
unsigned long num;
[unique,size_is(num)] struct_2_t *val;
} struct_3_t;
void
Test(
[in] handle_t bind_handle,
[out] struct_3_t *res,
[out] error_status_t *dce_status
);
}
The culprit is data member of struct_2_t - if it is the only member in the
structure, or if it is removed, the data marshaling works fine.
SERVER:
#include <windows.h>
#include <rpc.h>
#include <time.h>
#include <stdlib.h>
#include "iface.h"
void WINAPI Test(
/* [in] */ handle_t bind_handle,
/* [out] */ struct_3_t *res,
/* [fault_status][comm_status][out] */ error_status_t *dce_status)
{
res->num = 1;
res->val = malloc(sizeof(struct_2_t));
res->val[0].status = 0;
res->val[0].data = NULL;
}
int main()
{
RPC_STATUS status;
status = RpcServerUseProtseqEp("ncacn_ip_tcp", // Use TCP/IP
RPC_C_PROTSEQ_MAX_REQS_DEFAULT, //
Backlog queue length for TCP/IP.
"1999", // TCP/IP port to use.
NULL); // No security.
if (status)
exit(status);
status = RpcServerRegisterIf(iface_v1_0_s_ifspec, // Interface to
register.
NULL, // Use the MIDL generated entry-point
vector.
NULL); // Use the MIDL generated entry-point
vector.
if (status)
exit(status);
status = RpcServerListen(1, // Recommended minimum number of threads.
RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended
FALSE); // Start listening now.
if (status)
exit(status);
}
void __RPC_FAR * __RPC_USER
midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER
midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}
CLIENT:
#include <windows.h>
#include <rpc.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "iface.h"
int main()
{
RPC_STATUS status;
handle_t hBinding = NULL;
unsigned char* szStringBinding = NULL;
error_status_t rc = 0;
status = RpcStringBindingCompose(NULL, // UUID to bind to.
"ncacn_ip_tcp", // Use TCP/IP
"localhost", // TCP/IP network
"1999", // TCP/IP port to use.
NULL, // Protocol dependent network
options to use.
&szStringBinding); // String binding
output.
if (status)
exit(status);
status = RpcBindingFromStringBinding(szStringBinding, // The string
binding to validate.
&hBinding); // Put the result in
the implicit binding
if (status)
exit(status);
RpcTryExcept
{
struct_3_t res = {0};
Test(hBinding, &res, &rc);
}
RpcExcept(1)
{
printf("Exception: %x\n", RpcExceptionCode());
}
RpcEndExcept
printf("Result: %x\n", rc);
status = RpcBindingFree(&hBinding); // Frees the binding handle.
if (status)
exit(status);
}
void __RPC_FAR * __RPC_USER
midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER
midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}
I would appreciate any help on the issue.