Thread: [Error] - Cant send array from client (WinAPI / Remote Procedure Call)

  1. #1
    Registered User OffyGhost's Avatar
    Join Date
    May 2011
    Posts
    6

    [Error] - Cant send array from client (WinAPI / Remote Procedure Call)

    I have almost completed this very hard task on VS 2005 C++. There is is only part of prog, that I need to fix

    Client:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <iostream>
    #include <ctype.h>
    #include <windows.h>
    #include "hello.h"
    using namespace std;
    #pragma comment(lib,"rpcndr.lib")
    #pragma comment(lib,"rpcns4.lib")
    #pragma comment(lib,"rpcrt4.lib")
    
    void main()
    {
      char buffer[8] = "";
    	int N;
    	int k = 0;
    	while(k==0)
    	{
    		printf("Enter size of matrix (from 2 to 20): N=");
    		scanf ("%d", &N);
    		sprintf(buffer, "%d", N);
    		if ((N<2) || (N>20)) k=0;
    		else k=1;
    	}
    	unsigned short matrix [20][20];
    	cout << "Fill the matrix:\n";
    	for (size_t i = 0; i < N; ++i) 
    	{
    		for (size_t j = 0; j < N; ++j)
    		{
    			cin >> matrix[i][j];
    		}
    	}
    	cout << "\nCurrent matrix... \n";
    	for (size_t i = 0; i < N; ++i) 
    	{
    		for (size_t j = 0; j < N; ++j) 
    		{
    			cout << matrix[i][j] << "  ";
    		}
    		cout << endl << endl;
    	}
    RPC_STATUS status;
    const char* pszUuid = "906B0CE0-C70B-1067-B317-00DD010662DC";
    const char* pszProtocolSequence = "ncacn_np";
    const char* pszNetworkAddress = "127.0.0.1";
    const char* pszEndpoint = "\\pipe\\he";
    const char* pszOptions = NULL;
    const char* pszStringBinding = NULL;
    long ulCode=0;
    status = RpcStringBindingCompose((RPC_CSTR)pszUuid,(RPC_CSTR) pszProtocolSequence, (RPC_CSTR)pszNetworkAddress, (RPC_CSTR)pszEndpoint, (RPC_CSTR)pszOptions, (RPC_CSTR*)&pszStringBinding);
    if (status) exit(status);
    status = RpcBindingFromStringBinding((RPC_CSTR)pszStringBinding, &hello_IfHandle);
    if (status) exit(status);
    RpcTryExcept
    {
    	HelloProc((unsigned char *)buffer, (unsigned char **) matrix);
    	Shutdown();
    }
    RpcExcept(1)
    {
    	ulCode = RpcExceptionCode();
    	printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
    } 
    RpcEndExcept
        status = RpcStringFree ((RPC_CSTR*)&pszStringBinding);
        if (status)    exit (status);
    status = RpcBindingFree(&hello_IfHandle);
    if (status) exit(status);
    system("pause");
    }
    
    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);
    }
    Server:
    Code:
    // lab7_server.cpp : Defines the entry point for the console application.
    //
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <ctype.h>
    #include <iostream>
    #include "hello.h"
    using namespace std;
    
    #pragma comment(lib,"RpcNdr.lib")
    #pragma comment(lib,"Rpcns4.lib")
    #pragma comment(lib,"RpcRT4.lib")
    
    void main()
    {
    	char buffer[8];
    	char matrix[20][20];
    
    RPC_STATUS status;
    const char* pszProtocolSequence = "ncacn_np";
    const char* pszSecurity = NULL;
    const char* pszEndpoint = "\\pipe\\he";
    const int cMinCalls = 1;
    const int cMaxCalls = 20;
    const int fDontWait = FALSE;
    status = RpcServerUseProtseqEp((RPC_CSTR)pszProtocolSequence, cMaxCalls, (RPC_CSTR)pszEndpoint, (RPC_CSTR)pszSecurity);
    if (status) exit(status);
    status = RpcServerRegisterIf(hello_v1_0_s_ifspec, NULL, NULL);
    if (status) exit(status);
    status = RpcServerListen(cMinCalls, cMaxCalls, fDontWait);
    if (status) exit(status);
    } 
    
    void HelloProc(unsigned char * buffer, unsigned char ** matrix)
    {		
    	int N;
    	N=atoi((char*)buffer);
    	cout << "Size of matrix from client= " << N << endl;
    	int **matrix_transfered = new int*[N];
    	for (size_t i = 0; i < N; ++i) 
    	{
    		matrix_transfered[i] = new int[N];
    	}
    	for (size_t i = 0; i < N; ++i) 
    	{
    		for (size_t j = 0; j < N; ++j)
    		{	
    			matrix_transfered[i][j]=atoi((const char *) matrix[i][j]);
    		}
    	}
    	
    	cout << "\nMatrix from client... \n";
    	for (size_t i = 0; i < N; ++i) 
    	{
    		for (size_t j = 0; j < N; ++j) 
    		{
    			cout << matrix_transfered[i][j] << "  ";
    		}
    		cout << endl << endl;
    	}
    	system("PAUSE");
    }
    void Shutdown(void)
    {
    RPC_STATUS status;
    printf("Вызываем RpcMgmtStopServerListening\n");
    status = RpcMgmtStopServerListening(NULL);
    printf("RpcMgmtStopServerListening returned: 0x%x\n", status);
    if (status)
    {
    exit(status);
    }
    printf("Вызываем RpcServerUnregisterIf\n");
    status = RpcServerUnregisterIf(NULL, NULL, FALSE);
    printf("RpcServerUnregisterIf возвратила 0x%x\n", status);
    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);
    }
    Hello.h:
    Code:
    /* this ALWAYS GENERATED file contains the definitions for the interfaces */
    
    
     /* File created by MIDL compiler version 6.00.0366 */
    /* at Sat May 28 09:27:22 2011
     */
    /* Compiler settings for hello.idl:
        Oicf, W1, Zp8, env=Win32 (32b run)
        protocol : dce , ms_ext, c_ext, robust
        error checks: allocation ref bounds_check enum stub_data 
        VC __declspec() decoration level: 
             __declspec(uuid()), __declspec(selectany), __declspec(novtable)
             DECLSPEC_UUID(), MIDL_INTERFACE()
    */
    //@@MIDL_FILE_HEADING(  )
    
    #pragma warning( disable: 4049 )  /* more than 64k source lines */
    
    
    /* verify that the <rpcndr.h> version is high enough to compile this file*/
    #ifndef __REQUIRED_RPCNDR_H_VERSION__
    #define __REQUIRED_RPCNDR_H_VERSION__ 475
    #endif
    
    #include "rpc.h"
    #include "rpcndr.h"
    
    #ifndef __RPCNDR_H_VERSION__
    #error this stub requires an updated version of <rpcndr.h>
    #endif // __RPCNDR_H_VERSION__
    
    
    #ifndef __hello_h__
    #define __hello_h__
    
    #if defined(_MSC_VER) && (_MSC_VER >= 1020)
    #pragma once
    #endif
    
    /* Forward Declarations */ 
    
    #ifdef __cplusplus
    extern "C"{
    #endif 
    
    void * __RPC_USER MIDL_user_allocate(size_t);
    void __RPC_USER MIDL_user_free( void * ); 
    
    #ifndef __hello_INTERFACE_DEFINED__
    #define __hello_INTERFACE_DEFINED__
    
    /* interface hello */
    /* [implicit_handle][unique][version][uuid] */ 
    
    void HelloProc( 
        /* [string][in] */ unsigned char *buffer,
        /* [string][in] */ unsigned char **matrix);
    
    void Shutdown( void);
    
    
    extern handle_t hello_IfHandle;
    
    
    extern RPC_IF_HANDLE hello_v1_0_c_ifspec;
    extern RPC_IF_HANDLE hello_v1_0_s_ifspec;
    #endif /* __hello_INTERFACE_DEFINED__ */
    
    /* Additional Prototypes for ALL interfaces */
    
    /* end of Additional Prototypes */
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    Errors:
    error LNK2001: unresolved external symbol _HelloProc
    fatal error LNK1120: 1 unresolved externals

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    In your header file, your HelloProc prototype is wrapped in an extern "C" declaration. So either you need to bend reality to fit that description (by writing your HelloProc in C, not C++, and compiling it as such), or bend the description to fit reality (by letting the compiler do the C++ name mangling).

  3. #3
    Registered User OffyGhost's Avatar
    Join Date
    May 2011
    Posts
    6

    c or c++

    char buffer succesful sent, when I add matrix in the program all the stops working

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Your matrix is a two-dimensional array, which is not at all similar to the char ** your function expects. Again, you need to change one to match the other.

  5. #5
    Registered User OffyGhost's Avatar
    Join Date
    May 2011
    Posts
    6
    Rewriten
    in client
    Code:
    ...
    	unsigned char **matrix = new unsigned char*[N];
    	for (size_t i = 0; i < N; ++i) 
    	{
    		matrix[i] = new unsigned  char[N];
    	}
    ...
    HelloProc((unsigned char *)buffer, (unsigned char **) matrix);
    in server:
    Code:
    void HelloProc(unsigned char * buffer, unsigned char ** matrix)
    ...
    hello.h
    Code:
    void HelloProc( 
        /* [string][in] */ unsigned char *buffer,
        /* [string][in] */ unsigned char **matrix);
    Im succesful send buffer, but when start send the matrix - critical error[Error] - Cant send array from client (WinAPI / Remote Procedure Call)-test-jpg

    error somewhere in this:
    Code:
    			matrix_transfered[i][j]=atoi((char *) matrix[i][j]);
    Last edited by OffyGhost; 05-28-2011 at 02:11 AM.

  6. #6
    Registered User Inanna's Avatar
    Join Date
    May 2011
    Posts
    69
    matrix[i][j] is just a char, not a char* that atoi() expects. You can do atoi(matrix[i]) if matrix[i] is really a string with an ending null character. But I am doubtful about it being a real string since the array is of unsigned char. You might need to make a real string with the current length of matrix[i]:
    Code:
    char* temp = new char[length+1];
    
    for (int x = 0; x < length; ++x)
        temp[x] = matrix[i][x];
    temp[length] = '\0';
    
    matrix_transfered[i][j] = atoi(temp);
    delete[] temp;

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You need to decide whether your matrix is really going to give you a matrix of ints -- you have a matrix of digits at least, I guess. If you want to translate each digit into it's 0 through 9 equivalent, you should just subtract '0' from the character to get the value. If you want numbers bigger than 10, then you should probably be transforming a row at a time (which means you have too many elements in your array).

  8. #8
    Registered User OffyGhost's Avatar
    Join Date
    May 2011
    Posts
    6
    Code:
    char* temp = new char[length+1];
    
    for (int x = 0; x < length; ++x)
        temp[x] = matrix[i][x];
    temp[length] = '\0';
    
    matrix_transfered[i][j] = atoi(temp);
    delete[] temp;
    doesn't work
    all symbols in matrix = 0

    Code:
    void HelloProc( 
        /* [string][in] */ unsigned char *buffer,
        /* [in] */ int **matrix);
    
    void HelloProc(unsigned char * buffer, int ** matrix)
    I send int matrix:
    2 1 2

    4 5 6

    7 3 2

    And got int matrix on server:
    2 2 -1970798541

    -1 2089922106 2089921100

    -2081649835 1448282348 -1946397353

    =(
    Last edited by OffyGhost; 05-31-2011 at 08:52 PM.

  9. #9
    Registered User OffyGhost's Avatar
    Join Date
    May 2011
    Posts
    6
    where can I find a lot of examples on RPC?

  10. #10
    Registered User OffyGhost's Avatar
    Join Date
    May 2011
    Posts
    6
    In Visual Studio 2005 SDK no examples for RPC..

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to Send Mac Address From Client to Server
    By Lieyza197 in forum C Programming
    Replies: 2
    Last Post: 05-27-2009, 09:58 AM
  2. i have this problem with RPC (Remote Procedure Calls)
    By gorett in forum Linux Programming
    Replies: 0
    Last Post: 01-22-2007, 05:44 PM
  3. Client works on a LAN but don't send all the data
    By Niara in forum Networking/Device Communication
    Replies: 9
    Last Post: 01-04-2007, 04:44 PM
  4. Call procedure in DLL
    By Mithoric in forum Windows Programming
    Replies: 4
    Last Post: 01-04-2004, 08:17 AM
  5. Remote Procedure Call
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 02-23-2002, 08:43 AM

Tags for this Thread