Thread: How do I pass pointer structure to function then cast to diff structure

  1. #1
    Registered User
    Join Date
    Jul 2017
    Posts
    28

    How do I pass pointer structure to function then cast to diff structure

    I'm trying to create a .so in C to interface with an external program. Theexternal program only accepts functions that have pointers to structures in thedefinition. See the comments ‘Broken Function’ in my code below. I need thefunction declaration to be defined as in my code with ‘struct sockaddr_in6*serv_addr’.

    The problem is that the ‘bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr))’ onlyworks if it is in the main() function. It gives an error, if I call it from mycustom function. I believe that the error is caused when I try to castserv_addr into a pointer structure.

    My coworker and I cannot figureout how to get the reference in the bind() function that we need in thefunction without changing our custom function declaration. Is it possible toget the reference that we need without changing our custom function declaration?

    Thanks.


    My Code:
    Code:
    // Includes
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<netdb.h>
    
    #include<arpa/inet.h>
    
    #include<stddef.h>
    
    
    // Function Declarations
    void getServerAddrJ(int sockfd, int portNum, struct sockaddr_in6*serv_addr);
    
    int serverBindListenJ(int sockfd, struct sockaddr_in6*serv_addr); // Broken Function
    
    
    // Main
    int main(void) {
    // Declare Vars
    int portno = 3344;
    
    int sockfd, tempVar;
    
    struct sockaddr_in6serv_addr; // serv_addr Definition
    
    
    // Sockets Layer Call: socket()
        sockfd = socket(AF_INET6,SOCK_STREAM, 0);
    
    // Parse Addr
        getServerAddrJ(sockfd, portno,&serv_addr);
    
        //This function needs to pass in &serv_addr
        tempVar = serverBindListenJ(sockfd,&serv_addr); // Broken function
    
    printf("\nSuccess= %d\n", tempVar);
    
    // More Code…
    
    return(0);
    }
    // End Main
    
    
    void getServerAddrJ(int sockfd, int portNum, struct sockaddr_in6*serv_addr) {
    // ParseAddress
          serv_addr->sin6_flowinfo = 0;
          serv_addr->sin6_family = AF_INET6; // AF_INET6 =10;
          serv_addr->sin6_addr = in6addr_any;
          serv_addr->sin6_port = htons(portNum); // Convert theport number to network byte order
    
    }
    
    
    // Broken function
    // This function needs to have the argument ‘struct sockaddr_in6*serv_addr’
    int serverBindListenJ(int sockfd, struct sockaddr_in6*serv_addr) {
    // SocketsLayer Call: bind()
    int tmpVar;
    
          tmpVar= bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)); //The bind() works if it is in main(), but not in its own function
    
    
    // Bind()Error Catch
    if (tmpVar < 0){
    return(-1);
          }
    
    // SocketsLayer Call: listen()
          tmpVar= listen(sockfd, 5);
    
    // Listen()Error Catch
    return(tmpVar);
    }



  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,993
    You need to fix all the font abuse in your post.

    Remove all the colour / font / size tags from your prose, and make sure you "paste as text" between [code][/code] tags.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jul 2017
    Posts
    28
    Sorry, I had copied my question over from MS Word and the formatting with terrible.

    I did manage to figure out my problem though.

    I had to use the following code in my function to recreate the structure after passing it in.


    Code:
    struct sockaddr_in6 serv_addr2 = *serv_addr;
    
    tmpVar = bind(sockfd, (struct sockaddr *) &serv_addr2, sizeof(serv_addr2));
    Last edited by JHugh; 08-02-2017 at 07:56 AM. Reason: Fixed code formatting

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,993
    WTF are you doing anywhere near M$word?

    You should be copying code directly from your source code editor, not an etch-a-sketch.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by JHugh View Post
    I did manage to figure out my problem though.
    I had to use the following code in my function to recreate the structure after passing it in.
    Code:
    struct sockaddr_in6 serv_addr2 = *serv_addr;
    tmpVar = bind(sockfd, (struct sockaddr *) &serv_addr2, sizeof(serv_addr2));
    Your fix is suboptimal.

    In main, serv_addr is NOT a pointer, but bind requires a pointer, so you need to use the & to pass the address, and you can use serv_addr itself with the sizeof operator to get the size:
    Code:
    // in main
    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    But in the function, serv_addr is now a pointer, so it can be used without the &, and to get the correct size from the sizeof operator, you need to use *:
    Code:
    // in serverBindListenJ
    bind(sockfd, (struct sockaddr *) serv_addr, sizeof(*serv_addr));
    That's all you had to do.

    BTW, 'tmpVar' is a hideously bad name. It has no meaning at all! 'status' would be better.

  6. #6
    Registered User
    Join Date
    Jul 2017
    Posts
    28
    Quote Originally Posted by algorism View Post
    Your fix is suboptimal.

    In main, serv_addr is NOT a pointer, but bind requires a pointer, so you need to use the & to pass the address, and you can use serv_addr itself with the sizeof operator to get the size:
    Code:
    // in main
    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    But in the function, serv_addr is now a pointer, so it can be used without the &, and to get the correct size from the sizeof operator, you need to use *:
    Code:
    // in serverBindListenJ
    bind(sockfd, (struct sockaddr *) serv_addr, sizeof(*serv_addr));
    That's all you had to do.

    BTW, 'tmpVar' is a hideously bad name. It has no meaning at all! 'status' would be better.
    Thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to pass a structure to a function
    By zolfaghar in forum C Programming
    Replies: 2
    Last Post: 05-10-2016, 09:31 AM
  2. How to pass pointer to a structure in a message queue
    By smitsaboo in forum C Programming
    Replies: 4
    Last Post: 08-15-2009, 11:33 PM
  3. pass structure to function
    By tat in forum C Programming
    Replies: 18
    Last Post: 12-06-2007, 08:01 PM
  4. how to cast a char *mystring to a structure pointer ??
    By hanhao in forum C++ Programming
    Replies: 1
    Last Post: 03-29-2004, 08:59 AM

Tags for this Thread