返回值为空的函数指针如何定义

时间:2023-01-31 19:37:52

int  (__stdcall *gethostname1)(char *,int ); 
我用这样的方式定义函数指针   如果函数返回值为空的函数如何定义?

void (__stdcall *freeaddrinfo1)(struct addrinfo *); 我这样定义  编译报错

我要保存ws2_32.dll中的函数的调用地址  我想知道怎么定义指针保存这个地址 

所以不要告诉我用可以其他的方法直接访问DLL中的函数  




//之前这种定义
int  (__stdcall *gethostname1)(char *,int ); 
//这种使用
proc=GetProcAddress(hModule,"gethostname");
gethostname1=(int  (__stdcall *)(char *,int ))proc;


都没问题


换成void的就不行

光定义这句void (__stdcall *freeaddrinfo1)(struct addrinfo *);就出错
改成这样typedef void (__stdcall *freeaddrinfo1)(struct addrinfo *);才不出错

proc的定义
FARPROC proc;     //函数指针入口

为了抛开proc类型的影响

改成这样写
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))GetProcAddress(hModule,"freeaddrinfo");


还是出错
E:\VC_WORK\GUA\sockfilter\winsock32.cpp(127) : error C2513: 'void (__stdcall *)(struct addrinfo *)' : no variable declared before '='



不知道要怎么写了

17 个解决方案

#1


你的完整代碼寫成咋樣都沒發出來。。。

#2


补上完整代码

//xxx.h文件
//相关变量申明
HMODULE hModule = NULL;  //模块句柄
char buffer[1000];    //缓冲区
FARPROC proc;     //函数指针入口

//定义指向原WinSock函数库地址的指针变量
SOCKET  (__stdcall *socket1)(int ,int,int); //创建Sock函数
int  (__stdcall *WSAStartup1)(WORD,LPWSADATA); //初始化WinSock库函数
int  (__stdcall *WSACleanup1)(); //清除WinSock库函数
int  (__stdcall *recv1)(SOCKET,char FAR *,int,int); //接收数据函数
int  (__stdcall *send1)(SOCKET,const char *,int,int); //发送数据函数
int  (__stdcall *connect1)(SOCKET,const struct sockaddr *,int); //创建连接函数
int  (__stdcall *bind1)(SOCKET,const struct sockaddr *,int); //绑定函数
//…………
//…………
//在后面继续添加其他winsock32库函数中需要自定义的函数地址的指针变量
int  (__stdcall *setsockopt1)(SOCKET,int,int,const char *,int); //sets a socket option
int  (__stdcall *getsockopt1)(SOCKET,int,int,char *,int *); //Gets a socket option
int  (__stdcall *WSARecvFrom1)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,struct sockaddr *,LPINT,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE); //receives a datagram and stores the source address.
int  (__stdcall *WSARecv1)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE); 
SOCKET  (__stdcall *accept1)(SOCKET,struct sockaddr *,int *);
int  (__stdcall *closesocket1)(SOCKET);
int  (__stdcall *getpeername1)(SOCKET,struct sockaddr *,int *);
int  (__stdcall *getsockname1)(SOCKET,struct sockaddr *,int *);
u_long   (__stdcall *htonl1)(u_long);
u_short   (__stdcall *htons1)(u_short);
int  (__stdcall *ioctlsocket1)(SOCKET,long,u_long *);
unsigned long (__stdcall *inet_addr1)(const char *);
char*  (__stdcall *inet_ntoa1)(struct   in_addr );
int  (__stdcall *listen1)(SOCKET,int );
u_long  (__stdcall *ntohl1)(u_long );
u_short  (__stdcall *ntohs1)(u_short );
int  (__stdcall *recvfrom1)(SOCKET,char *,int,int,struct sockaddr *,int * );
int  (__stdcall *select1)(int ,fd_set *,fd_set *,fd_set *,const struct timeval *);
int  (__stdcall *sendto1)(SOCKET,const char *,int,int,const struct sockaddr *,int);
int  (__stdcall *shutdown1)(SOCKET,int);
BOOL  (__stdcall *WSApSetPostRoutine1)(PVOID);  //没有MSDN资料的函数
//void  (__stdcall *FreeAddrInfoW1)(PADDRINFOW);
struct hostent*  (__stdcall *gethostbyname1)(const char *);
HANDLE  (__stdcall *WSAAsyncGetHostByName1)(HWND ,u_int ,const char *,char *,int);//没有MSDN资料的函数
int  (__stdcall *WSACancelAsyncRequest1)(HANDLE);  
int  (__stdcall *gethostname1)(char *,int ); 
typedef void (__stdcall *freeaddrinfo1)(struct addrinfo *);


//XXX.CPP文件
#include <stdio.h>

#include <winsock2.h>
#include <windows.h>
//#include <ws2tcpip.h>
//#include <wspiapi.h>
#include "winsock32.h"


//DLLMain函数入口
BOOL WINAPI DLLMain (HANDLE hInst,ULONG ul_reason_for_call,LPVOID lpReserved)
{
if(hModule==NULL)
{
//加载原来的WinSock库,原来的WinSock库被复制成wsock32.001
hModule=LoadLibrary("wsock32.001");
}
else return 1;
//获取原来WinSock库中所有的函数的地址并保存起来
if(hModule!=NULL)
{
//获取原来WinSock库初始化函数的地址,保存到WSAStartup1中
proc=GetProcAddress(hModule,"WSAStartup");
WSAStartup1=(int (__stdcall *)(WORD,LPWSADATA))proc;
//获取原来WinSock库清除函数的地址,保存到WSACleanup1中
proc=GetProcAddress(hModule,"WSACleanup");
WSACleanup1=(int (_stdcall *)())proc;
//接收数据函数
proc=GetProcAddress(hModule,"recv");
recv1=(int  (__stdcall *)(SOCKET,char FAR *,int,int))proc;
//发送数据函数
proc=GetProcAddress(hModule,"send");
send1=(int  (__stdcall *)(SOCKET,const char *,int,int))proc;
//创建连接函数
proc=GetProcAddress(hModule,"connect");
connect1=(int  (__stdcall *)(SOCKET,const struct sockaddr *,int))proc;
//绑定函数
proc=GetProcAddress(hModule,"bind");
bind1=(int  (__stdcall *)(SOCKET,const struct sockaddr *,int))proc;
//…………
//…………
//在后面继续把原来WinSock库中所有的函数的地址保存起来
proc=GetProcAddress(hModule,"setsockopt");
setsockopt1=(int  (__stdcall *)(SOCKET,int,int,const char *,int))proc;


//中间N个函数代码略

//其他未修改函数
proc=GetProcAddress(hModule,"gethostname");
gethostname1=(int  (__stdcall *)(char *,int ))proc;
//其他未修改函数
// proc=GetProcAddress(hModule,"freeaddrinfo");
// freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))proc;
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))GetProcAddress(hModule,"freeaddrinfo");

}
else return 0;
return 1;
}




//定义库输出函数

//WinSock初始化函数定义
int PASCAL FAR WSAStartup(WORD wWersionRequested,LPWSADATA lpWSAData)
{
//调用原来的WinSock初始化函数
return WSAStartup1(wWersionRequested,lpWSAData);
}





//WinSock清除函数
int PASCAL FAR WSACleanup()
{
//调用原来的WinSock清除函数
return WSACleanup1();
}




//创建Socket函数
SOCKET PASCAL FAR socket(int af,int type,int protocol)
{
//调用原来的创建Socket函数
return socket1(af,type,protocol);
}

//中间N个函数定义略

int PASCAL FAR gethostname(char *name,int namelen)
{
return gethostname1(name,namelen);
}



//DEF文件
LIBRARY "sockfilter"
EXPORTS
;WSAStartup @1
;WSACleanup @2
;recv @3
;send @4
;socket @5
;bind @6
;closesocket @7
;connect @8

;其他输出函数列表
;…………
;…………


accept @1
bind @2
closesocket @3
connect @4 
getpeername @5 
getsockname @6 
getsockopt @7 
htonl @8 
htons @9 
ioctlsocket @10 
inet_addr @11 
inet_ntoa @12 
listen @13 
ntohl @14 
ntohs @15 
recv @16 
recvfrom @17 
select @18 
send @19 
sendto @20 
setsockopt @21 
shutdown @22 
socket @23 
WSApSetPostRoutine @24 
;FreeAddrInfoW @25 
;GetAddrInfoW @26 
;GetNameInfoW @27 
;WPUCompleteOverlappedRequest @28 
;WSAAccept @29 
;WSAAddressToStringA @30 
;WSAAddressToStringW @31 
;WSACloseEvent @32 
;WSAConnect @33 
;WSACreateEvent @34 
;WSADuplicateSocketA @35 
;WSADuplicateSocketW  @36 
;WSAEnumNameSpaceProvidersA @37 
;WSAEnumNameSpaceProvidersW @38 
;WSAEnumNetworkEvents @39 
;WSAEnumProtocolsA @40 
;WSAEnumProtocolsW @41 
;WSAEventSelect @42 
;WSAGetOverlappedResult @43 
;WSAGetQOSByName @44 
;WSAGetServiceClassInfoA @45 
;WSAGetServiceClassInfoW WSAGetServiceClassInfoW @46 
;WSAGetServiceClassNameByClassIdA @47 
;WSAGetServiceClassNameByClassIdW @48 
;WSAHtonl @49 
;WSAHtons @50 
;gethostbyaddr @51 
gethostbyname @52 
;getprotobyname @53 
;getprotobynumber @54 
;getservbyname @55 
;getservbyport @56 
gethostname @57 
;WSAInstallServiceClassA @58 
;WSAInstallServiceClassW @59 
;WSAIoctl @60 
;WSAJoinLeaf @61 
;WSALookupServiceBeginA @62 
;WSALookupServiceBeginW @63 
;WSALookupServiceEnd @64 
;WSALookupServiceNextA @65 
;WSALookupServiceNextW @66 
;WSANSPIoctl @67 
;WSANtohl @68 
;WSANtohs @69 
;WSAProviderConfigChange @70 
WSARecv @71 
;WSARecvDisconnect @72 
WSARecvFrom @73 
;WSARemoveServiceClass @74 
;WSAResetEvent @75 
;WSASend @76 
;WSASendDisconnect @77 
;WSASendTo @78 
;WSASetEvent WSASetEvent @79 
;WSASetServiceA @80 
;WSASetServiceW @81 
;WSASocketA WSASocketA @82 
;WSASocketW WSASocketW @83 
;WSAStringToAddressA @84 
;WSAStringToAddressW @85 
;WSAWaitForMultipleEvents @86 
;WSCDeinstallProvider @87 
;WSCEnableNSProvider @88 
;WSCEnumProtocols @89 
;WSCGetProviderPath @90 
;WSCInstallNameSpace @91 
;WSCInstallProvider @92 
;WSCUnInstallNameSpace @93 
;WSCUpdateProvider @94 
;WSCWriteNameSpaceOrder @95 
;WSCWriteProviderOrder @96 
; freeaddrinfo @97 
;getaddrinfo @98 
;getnameinfo @99 
;Noname100 Noname100 @100 NONAME 
;WSAAsyncSelect @101 
;WSAAsyncGetHostByAddr @102 
WSAAsyncGetHostByName @103 
;WSAAsyncGetProtoByNumber @104 
;WSAAsyncGetProtoByName @105 
;WSAAsyncGetServByPort @106 
;WSAAsyncGetServByName @107 
WSACancelAsyncRequest @108 
;WSASetBlockingHook @109 
;WSAUnhookBlockingHook @110 
;WSAGetLastError @111 
;WSASetLastError @112 
;WSACancelBlockingCall @113 
;WSAIsBlocking @114 
WSAStartup @115 
WSACleanup @116 

#3


typedef void (__stdcall *freeaddrinfo1)(struct addrinfo *);
freeaddrinfo addrinfo;
addrinfo=( freeaddrinfo1)GetProcAddress(hModule,"freeaddrinfo");

#4


void (__stdcall *freeaddrinfo1)(struct addrinfo *);

应该没问题

typedef void (__stdcall *FUN)(struct addrinfo *);
然后再FUN freeaddrinfo1;
这样可以不?

#5


你是对函数指针的问题没搞清楚.
举个例子:

typedef (*test)(int,int);

test a,b;

等价于:

void (*a)(int,int);
void (*b)(int,int);

这里的两个a和b已经是一个实际的函数指针, 它指向的是以两个整型数据为参数,不返回值的指针.  而typedef (*test)(int,int);定义的是一个类型的函数指针,它可以实例化.  就像test a,b;  a、b是两个属于一种类型的函数指针

你代码中的
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))proc; 
相当于强制类型转化,不能这样用.
freeaddrinfo1=(类型)proc;

比如说你可以像这样,  freeaddrinfo1=(test)proc;  将其强制转换成test这种类型的指针,这样就可以了.

再不清楚, 去看看typedef关于函数指针的用法

#6


补充个测试的小例子
#include "iostream.h"

void xxx(int,int);

typedef void (*test)(int,int);

test t1;

void (*a)(int,int);

int main()
{
a=xxx;
a(1,1);

t1=xxx;
t1(2,2);

return 0;
}

void xxx(int a,int b)
{
cout<<"a+b="<<a+b<<endl;
}

#7


引用 5 楼 oathevil 的回复:
你是对函数指针的问题没搞清楚.
举个例子:

typedef (*test)(int,int);

test a,b;

等价于:

void (*a)(int,int);
void (*b)(int,int);

这里的两个a和b已经是一个实际的函数指针, 它指向的是以两个整型数据为参数,不返回值的指针.  而typedef (*test)(int,int);定义的是一个类型的函数指针,它可以实例化.  就像test a,b;  a、b是两个属于一种类型的函数指针

你代码中的
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))proc;
相当于强制类型转化,不能这样用.
freeaddrinfo1=(类型)proc;

比如说你可以像这样,  freeaddrinfo1=(test)proc;  将其强制转换成test这种类型的指针,这样就可以了.

再不清楚, 去看看typedef关于函数指针的用法
谢谢  这个看了你的说明之后  我已经清楚了



那现在int  (__stdcall *gethostname1)(char *,int ); 
这种声明方式应该怎么理解? 
为什么在返回值为void 的情况下  语法就不支持了呢?

#8


int  (__stdcall *gethostname1)(char *,int ); 
这是声明一个函数指针gethostname1
而函数指针的所指针的函数是一个参数类型依次是char *,int   且返回值为int的函数

在返回值为空的情况下, 当然会提示错误啦.

#9


引用 8 楼 oathevil 的回复:
int  (__stdcall *gethostname1)(char *,int );
这是声明一个函数指针gethostname1
而函数指针的所指针的函数是一个参数类型依次是char *,int  且返回值为int的函数

在返回值为空的情况下, 当然会提示错误啦.


我指的是返回值为空的情况下  我定义当然就void  (__stdcall *gethostname1)(char *,int ); 
这样定义了   

#10


我在.H文件中这样定义时
void (__stdcall *freeaddrinfo1)(struct addrinfo *);

CPP文件什么都不写  就提示错误
E:\VC_WORK\GUA\sockfilter\winsock32.cpp(402) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1786) 
         Please choose the Technical Support command on the Visual C++ 
         Help menu, or open the Technical Support help file for more information

#11


我在CPP文件中仿照返回值不为空的函数的写法 写出了如下代码

//其他未修改函数
proc=GetProcAddress(hModule,"freeaddrinfo");
freeaddrinfo1=(void (__stdcall *)(struct addrinfo *))proc;


报错

e:\vc_work\gua\sockfilter\winsock32.cpp(137) : error C2440: '=' : cannot convert from '<Unknown>' to '<Unknown>'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast

#12


struct  addrinfo
{
//
};

void (__stdcall *freeaddrinfo1)(struct addrinfo *);

你addrinfo这个结构体没定义吧?   像这样加上试试

#13


.H文件中
int  (__stdcall *gethostname1)(char *,int );
CPP文件中
//其他未修改函数
proc=GetProcAddress(hModule,"gethostname");
gethostname1=(int  (__stdcall *)(char *,int ))proc;

此写法正确  不报错

#14


int main(){return 0;}

#15


加上之后
winsock32.def : error LNK2001: unresolved external symbol freeaddrinfo
winsock32.def : error LNK2001: unresolved external symbol getaddrinfo
Debug/sockfilter.lib : fatal error LNK1120: 2 unresolved externals
LINK : fatal error LNK1141: failure during build of exports file

抱着个错

#16


貌似是的 没问题了
这个只是函数再导出表中申明 但是没实现的错误  

OK了 谢谢了  我知道怎么回事了
还是有未定义的类型付

我真的要换VS08了

#17


引用 16 楼 tendollor 的回复:
貌似是的 没问题了
这个只是函数再导出表中申明 但是没实现的错误  

OK了 谢谢了 我知道怎么回事了
还是有未定义的类型付

我真的要换VS08了

楼上 大神语法没问题了 
程序有问题么?

#1


你的完整代碼寫成咋樣都沒發出來。。。

#2


补上完整代码

//xxx.h文件
//相关变量申明
HMODULE hModule = NULL;  //模块句柄
char buffer[1000];    //缓冲区
FARPROC proc;     //函数指针入口

//定义指向原WinSock函数库地址的指针变量
SOCKET  (__stdcall *socket1)(int ,int,int); //创建Sock函数
int  (__stdcall *WSAStartup1)(WORD,LPWSADATA); //初始化WinSock库函数
int  (__stdcall *WSACleanup1)(); //清除WinSock库函数
int  (__stdcall *recv1)(SOCKET,char FAR *,int,int); //接收数据函数
int  (__stdcall *send1)(SOCKET,const char *,int,int); //发送数据函数
int  (__stdcall *connect1)(SOCKET,const struct sockaddr *,int); //创建连接函数
int  (__stdcall *bind1)(SOCKET,const struct sockaddr *,int); //绑定函数
//…………
//…………
//在后面继续添加其他winsock32库函数中需要自定义的函数地址的指针变量
int  (__stdcall *setsockopt1)(SOCKET,int,int,const char *,int); //sets a socket option
int  (__stdcall *getsockopt1)(SOCKET,int,int,char *,int *); //Gets a socket option
int  (__stdcall *WSARecvFrom1)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,struct sockaddr *,LPINT,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE); //receives a datagram and stores the source address.
int  (__stdcall *WSARecv1)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE); 
SOCKET  (__stdcall *accept1)(SOCKET,struct sockaddr *,int *);
int  (__stdcall *closesocket1)(SOCKET);
int  (__stdcall *getpeername1)(SOCKET,struct sockaddr *,int *);
int  (__stdcall *getsockname1)(SOCKET,struct sockaddr *,int *);
u_long   (__stdcall *htonl1)(u_long);
u_short   (__stdcall *htons1)(u_short);
int  (__stdcall *ioctlsocket1)(SOCKET,long,u_long *);
unsigned long (__stdcall *inet_addr1)(const char *);
char*  (__stdcall *inet_ntoa1)(struct   in_addr );
int  (__stdcall *listen1)(SOCKET,int );
u_long  (__stdcall *ntohl1)(u_long );
u_short  (__stdcall *ntohs1)(u_short );
int  (__stdcall *recvfrom1)(SOCKET,char *,int,int,struct sockaddr *,int * );
int  (__stdcall *select1)(int ,fd_set *,fd_set *,fd_set *,const struct timeval *);
int  (__stdcall *sendto1)(SOCKET,const char *,int,int,const struct sockaddr *,int);
int  (__stdcall *shutdown1)(SOCKET,int);
BOOL  (__stdcall *WSApSetPostRoutine1)(PVOID);  //没有MSDN资料的函数
//void  (__stdcall *FreeAddrInfoW1)(PADDRINFOW);
struct hostent*  (__stdcall *gethostbyname1)(const char *);
HANDLE  (__stdcall *WSAAsyncGetHostByName1)(HWND ,u_int ,const char *,char *,int);//没有MSDN资料的函数
int  (__stdcall *WSACancelAsyncRequest1)(HANDLE);  
int  (__stdcall *gethostname1)(char *,int ); 
typedef void (__stdcall *freeaddrinfo1)(struct addrinfo *);


//XXX.CPP文件
#include <stdio.h>

#include <winsock2.h>
#include <windows.h>
//#include <ws2tcpip.h>
//#include <wspiapi.h>
#include "winsock32.h"


//DLLMain函数入口
BOOL WINAPI DLLMain (HANDLE hInst,ULONG ul_reason_for_call,LPVOID lpReserved)
{
if(hModule==NULL)
{
//加载原来的WinSock库,原来的WinSock库被复制成wsock32.001
hModule=LoadLibrary("wsock32.001");
}
else return 1;
//获取原来WinSock库中所有的函数的地址并保存起来
if(hModule!=NULL)
{
//获取原来WinSock库初始化函数的地址,保存到WSAStartup1中
proc=GetProcAddress(hModule,"WSAStartup");
WSAStartup1=(int (__stdcall *)(WORD,LPWSADATA))proc;
//获取原来WinSock库清除函数的地址,保存到WSACleanup1中
proc=GetProcAddress(hModule,"WSACleanup");
WSACleanup1=(int (_stdcall *)())proc;
//接收数据函数
proc=GetProcAddress(hModule,"recv");
recv1=(int  (__stdcall *)(SOCKET,char FAR *,int,int))proc;
//发送数据函数
proc=GetProcAddress(hModule,"send");
send1=(int  (__stdcall *)(SOCKET,const char *,int,int))proc;
//创建连接函数
proc=GetProcAddress(hModule,"connect");
connect1=(int  (__stdcall *)(SOCKET,const struct sockaddr *,int))proc;
//绑定函数
proc=GetProcAddress(hModule,"bind");
bind1=(int  (__stdcall *)(SOCKET,const struct sockaddr *,int))proc;
//…………
//…………
//在后面继续把原来WinSock库中所有的函数的地址保存起来
proc=GetProcAddress(hModule,"setsockopt");
setsockopt1=(int  (__stdcall *)(SOCKET,int,int,const char *,int))proc;


//中间N个函数代码略

//其他未修改函数
proc=GetProcAddress(hModule,"gethostname");
gethostname1=(int  (__stdcall *)(char *,int ))proc;
//其他未修改函数
// proc=GetProcAddress(hModule,"freeaddrinfo");
// freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))proc;
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))GetProcAddress(hModule,"freeaddrinfo");

}
else return 0;
return 1;
}




//定义库输出函数

//WinSock初始化函数定义
int PASCAL FAR WSAStartup(WORD wWersionRequested,LPWSADATA lpWSAData)
{
//调用原来的WinSock初始化函数
return WSAStartup1(wWersionRequested,lpWSAData);
}





//WinSock清除函数
int PASCAL FAR WSACleanup()
{
//调用原来的WinSock清除函数
return WSACleanup1();
}




//创建Socket函数
SOCKET PASCAL FAR socket(int af,int type,int protocol)
{
//调用原来的创建Socket函数
return socket1(af,type,protocol);
}

//中间N个函数定义略

int PASCAL FAR gethostname(char *name,int namelen)
{
return gethostname1(name,namelen);
}



//DEF文件
LIBRARY "sockfilter"
EXPORTS
;WSAStartup @1
;WSACleanup @2
;recv @3
;send @4
;socket @5
;bind @6
;closesocket @7
;connect @8

;其他输出函数列表
;…………
;…………


accept @1
bind @2
closesocket @3
connect @4 
getpeername @5 
getsockname @6 
getsockopt @7 
htonl @8 
htons @9 
ioctlsocket @10 
inet_addr @11 
inet_ntoa @12 
listen @13 
ntohl @14 
ntohs @15 
recv @16 
recvfrom @17 
select @18 
send @19 
sendto @20 
setsockopt @21 
shutdown @22 
socket @23 
WSApSetPostRoutine @24 
;FreeAddrInfoW @25 
;GetAddrInfoW @26 
;GetNameInfoW @27 
;WPUCompleteOverlappedRequest @28 
;WSAAccept @29 
;WSAAddressToStringA @30 
;WSAAddressToStringW @31 
;WSACloseEvent @32 
;WSAConnect @33 
;WSACreateEvent @34 
;WSADuplicateSocketA @35 
;WSADuplicateSocketW  @36 
;WSAEnumNameSpaceProvidersA @37 
;WSAEnumNameSpaceProvidersW @38 
;WSAEnumNetworkEvents @39 
;WSAEnumProtocolsA @40 
;WSAEnumProtocolsW @41 
;WSAEventSelect @42 
;WSAGetOverlappedResult @43 
;WSAGetQOSByName @44 
;WSAGetServiceClassInfoA @45 
;WSAGetServiceClassInfoW WSAGetServiceClassInfoW @46 
;WSAGetServiceClassNameByClassIdA @47 
;WSAGetServiceClassNameByClassIdW @48 
;WSAHtonl @49 
;WSAHtons @50 
;gethostbyaddr @51 
gethostbyname @52 
;getprotobyname @53 
;getprotobynumber @54 
;getservbyname @55 
;getservbyport @56 
gethostname @57 
;WSAInstallServiceClassA @58 
;WSAInstallServiceClassW @59 
;WSAIoctl @60 
;WSAJoinLeaf @61 
;WSALookupServiceBeginA @62 
;WSALookupServiceBeginW @63 
;WSALookupServiceEnd @64 
;WSALookupServiceNextA @65 
;WSALookupServiceNextW @66 
;WSANSPIoctl @67 
;WSANtohl @68 
;WSANtohs @69 
;WSAProviderConfigChange @70 
WSARecv @71 
;WSARecvDisconnect @72 
WSARecvFrom @73 
;WSARemoveServiceClass @74 
;WSAResetEvent @75 
;WSASend @76 
;WSASendDisconnect @77 
;WSASendTo @78 
;WSASetEvent WSASetEvent @79 
;WSASetServiceA @80 
;WSASetServiceW @81 
;WSASocketA WSASocketA @82 
;WSASocketW WSASocketW @83 
;WSAStringToAddressA @84 
;WSAStringToAddressW @85 
;WSAWaitForMultipleEvents @86 
;WSCDeinstallProvider @87 
;WSCEnableNSProvider @88 
;WSCEnumProtocols @89 
;WSCGetProviderPath @90 
;WSCInstallNameSpace @91 
;WSCInstallProvider @92 
;WSCUnInstallNameSpace @93 
;WSCUpdateProvider @94 
;WSCWriteNameSpaceOrder @95 
;WSCWriteProviderOrder @96 
; freeaddrinfo @97 
;getaddrinfo @98 
;getnameinfo @99 
;Noname100 Noname100 @100 NONAME 
;WSAAsyncSelect @101 
;WSAAsyncGetHostByAddr @102 
WSAAsyncGetHostByName @103 
;WSAAsyncGetProtoByNumber @104 
;WSAAsyncGetProtoByName @105 
;WSAAsyncGetServByPort @106 
;WSAAsyncGetServByName @107 
WSACancelAsyncRequest @108 
;WSASetBlockingHook @109 
;WSAUnhookBlockingHook @110 
;WSAGetLastError @111 
;WSASetLastError @112 
;WSACancelBlockingCall @113 
;WSAIsBlocking @114 
WSAStartup @115 
WSACleanup @116 

#3


typedef void (__stdcall *freeaddrinfo1)(struct addrinfo *);
freeaddrinfo addrinfo;
addrinfo=( freeaddrinfo1)GetProcAddress(hModule,"freeaddrinfo");

#4


void (__stdcall *freeaddrinfo1)(struct addrinfo *);

应该没问题

typedef void (__stdcall *FUN)(struct addrinfo *);
然后再FUN freeaddrinfo1;
这样可以不?

#5


你是对函数指针的问题没搞清楚.
举个例子:

typedef (*test)(int,int);

test a,b;

等价于:

void (*a)(int,int);
void (*b)(int,int);

这里的两个a和b已经是一个实际的函数指针, 它指向的是以两个整型数据为参数,不返回值的指针.  而typedef (*test)(int,int);定义的是一个类型的函数指针,它可以实例化.  就像test a,b;  a、b是两个属于一种类型的函数指针

你代码中的
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))proc; 
相当于强制类型转化,不能这样用.
freeaddrinfo1=(类型)proc;

比如说你可以像这样,  freeaddrinfo1=(test)proc;  将其强制转换成test这种类型的指针,这样就可以了.

再不清楚, 去看看typedef关于函数指针的用法

#6


补充个测试的小例子
#include "iostream.h"

void xxx(int,int);

typedef void (*test)(int,int);

test t1;

void (*a)(int,int);

int main()
{
a=xxx;
a(1,1);

t1=xxx;
t1(2,2);

return 0;
}

void xxx(int a,int b)
{
cout<<"a+b="<<a+b<<endl;
}

#7


引用 5 楼 oathevil 的回复:
你是对函数指针的问题没搞清楚.
举个例子:

typedef (*test)(int,int);

test a,b;

等价于:

void (*a)(int,int);
void (*b)(int,int);

这里的两个a和b已经是一个实际的函数指针, 它指向的是以两个整型数据为参数,不返回值的指针.  而typedef (*test)(int,int);定义的是一个类型的函数指针,它可以实例化.  就像test a,b;  a、b是两个属于一种类型的函数指针

你代码中的
freeaddrinfo1=( void (__stdcall *)(struct addrinfo *))proc;
相当于强制类型转化,不能这样用.
freeaddrinfo1=(类型)proc;

比如说你可以像这样,  freeaddrinfo1=(test)proc;  将其强制转换成test这种类型的指针,这样就可以了.

再不清楚, 去看看typedef关于函数指针的用法
谢谢  这个看了你的说明之后  我已经清楚了



那现在int  (__stdcall *gethostname1)(char *,int ); 
这种声明方式应该怎么理解? 
为什么在返回值为void 的情况下  语法就不支持了呢?

#8


int  (__stdcall *gethostname1)(char *,int ); 
这是声明一个函数指针gethostname1
而函数指针的所指针的函数是一个参数类型依次是char *,int   且返回值为int的函数

在返回值为空的情况下, 当然会提示错误啦.

#9


引用 8 楼 oathevil 的回复:
int  (__stdcall *gethostname1)(char *,int );
这是声明一个函数指针gethostname1
而函数指针的所指针的函数是一个参数类型依次是char *,int  且返回值为int的函数

在返回值为空的情况下, 当然会提示错误啦.


我指的是返回值为空的情况下  我定义当然就void  (__stdcall *gethostname1)(char *,int ); 
这样定义了   

#10


我在.H文件中这样定义时
void (__stdcall *freeaddrinfo1)(struct addrinfo *);

CPP文件什么都不写  就提示错误
E:\VC_WORK\GUA\sockfilter\winsock32.cpp(402) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1786) 
         Please choose the Technical Support command on the Visual C++ 
         Help menu, or open the Technical Support help file for more information

#11


我在CPP文件中仿照返回值不为空的函数的写法 写出了如下代码

//其他未修改函数
proc=GetProcAddress(hModule,"freeaddrinfo");
freeaddrinfo1=(void (__stdcall *)(struct addrinfo *))proc;


报错

e:\vc_work\gua\sockfilter\winsock32.cpp(137) : error C2440: '=' : cannot convert from '<Unknown>' to '<Unknown>'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast

#12


struct  addrinfo
{
//
};

void (__stdcall *freeaddrinfo1)(struct addrinfo *);

你addrinfo这个结构体没定义吧?   像这样加上试试

#13


.H文件中
int  (__stdcall *gethostname1)(char *,int );
CPP文件中
//其他未修改函数
proc=GetProcAddress(hModule,"gethostname");
gethostname1=(int  (__stdcall *)(char *,int ))proc;

此写法正确  不报错

#14


int main(){return 0;}

#15


加上之后
winsock32.def : error LNK2001: unresolved external symbol freeaddrinfo
winsock32.def : error LNK2001: unresolved external symbol getaddrinfo
Debug/sockfilter.lib : fatal error LNK1120: 2 unresolved externals
LINK : fatal error LNK1141: failure during build of exports file

抱着个错

#16


貌似是的 没问题了
这个只是函数再导出表中申明 但是没实现的错误  

OK了 谢谢了  我知道怎么回事了
还是有未定义的类型付

我真的要换VS08了

#17


引用 16 楼 tendollor 的回复:
貌似是的 没问题了
这个只是函数再导出表中申明 但是没实现的错误  

OK了 谢谢了 我知道怎么回事了
还是有未定义的类型付

我真的要换VS08了

楼上 大神语法没问题了 
程序有问题么?