如何将Python Socket对象传递给用C编写的DLL?
有没有办法把 Python 的 socket 对象转换成一个空指针(void pointer)呢?
我在使用 ctypes,并且尝试过用 cast 和 Python 的转换函数。
我想把下面这段 C 代码转换成 Python:
long UNILIB_CALL UL_cbOpen ( void **psocket, char * ipAddress,
unsigned int port, int connectionTimeout, int sendTimeout, int recvTimeout)
{
printf("%s %d ",ipAddress,port);
long ssendTimeout=sendTimeout *100;
long rrecvTimeout=recvTimeout *100;
printf("Address:%u,%u,%u", psocket,*psocket,&psocket);
(*psocket) = (void*)socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("Address after:%u,%u,%u", psocket,*psocket,&psocket);
getchar();
RETURN_IF_ERRROR ((SOCKET)(*psocket) == INVALID_SOCKET,"SOCKET", 0);
long iResult=0;
//char RecvTimeout[21]; sprintf_s (RecvTimeout, sizeof RecvTimeout, "%d", recvTimeout);
iResult = setsockopt((SOCKET)(*psocket),SOL_SOCKET,SO_RCVTIMEO, (char*)&rrecvTimeout,
rrecvTimeout) ;
RETURN_IF_ERRROR ( iResult == SOCKET_ERROR,"setsockopt", WSAGetLastError());
char SendTimeout[21];
sprintf_s (SendTimeout, sizeof SendTimeout, "%d", sendTimeout);
iResult = setsockopt((SOCKET)(*psocket),SOL_SOCKET,SO_SNDTIMEO, (char*)&ssendTimeout,
sizeof ssendTimeout) ;
RETURN_IF_ERRROR ( iResult == SOCKET_ERROR,"setsockopt", WSAGetLastError());
SOCKADDR_IN clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( ipAddress );
clientService.sin_port = htons( port );
iResult = connect( (SOCKET)(*psocket), (SOCKADDR*) &clientService,
sizeof(clientService) );
RETURN_IF_ERRROR ( iResult == SOCKET_ERROR,"connect", WSAGetLastError());
return 1;
}
对应的 Python 代码是 ->
def UL_cbOpen(psocket,ipAddress,port,connectionTimeout,sendTimeout,recvTimeout):
print "Open CallBack\n";
print "PORT: {0}".format(port);
#print "IPAddress:{0}".format(ipAddress);
#print "Port:{0}".format(port);
ssendTimeout=c_long();
rrecvTimeout=c_long();
ssendTimeout=sendTimeout*100;
rrecvTimeout=recvTimeout*100;
try:
psocket=socks.socksocket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
print "Socket created";
except:
print "Failed to create socket";
psocket.setproxy(socks.PROXY_TYPE_SOCKS5,"my.web-proxy.example.com")
#PROXY_TYPE_SOCKS4,PROXY_TYPE_HTTP
hostname=gethostbyaddr(ipAddress);
psocket.setsockopt(SOL_SOCKET, SO_RCVTIMEO, rrecvTimeout);
psocket.setsockopt(SOL_SOCKET,SO_SNDTIMEO,ssendTimeout);
try:
psocket.connect((ipAddress,int(port)));
print "Connected to Printer";
except:
print "Failed Connection";
return 1;
这是一个回调函数,我用:
ulopen=WINFUNCTYPE(c_long,POINTER(c_void_p),c_char_p,c_uint,c_int,c_int,c_int);
来创建这个回调。UNILIB_CALL
是 __stdcall
,我用 WinDLL 来获取库的句柄。
当回调发生时,我遇到了一个错误:
Socket 指针必须已经分配。
有没有办法解引用一个指向指针的指针呢?
你能建议一些代码上的修改,让 socket 能像在 C 代码中那样处理吗?
2 个回答
0
套接字(Sockets)有一个叫做 fileno()
的函数。
你可以试着用这个函数,从这个文件描述符中创建一个新的套接字。
0
把Python对象转换成一个空指针是没用的。C语言的函数需要一个指向C语言套接字对象的指针,而Python的套接字对象和C语言的套接字对象是不一样的。
据我所知,你不能用这种方式在Python中获取一个可以给C程序使用的套接字。你为什么要这么做呢?