最近尝试将项目绑定C++的socket实现代码,结果尝试绑定其中一个类测试时发生了LNK2001错误,错误描述为:
error LNK2001: 无法解析的外部符号 “class JSObject * jsb_sockaddr_in_prototype” (?jsb_sockaddr_in_prototype@@3PAVJSObject@@A)
选择绑定的`类
CCInetAddress.h
#ifndef __CCNET_INETADDRESS_H__
#define __CCNET_INETADDRESS_H__
#include "cocos2d.h"
#include "CCNetMacros.h"
#include <string>
NS_CC_BEGIN
// dns parse
static std::string domainToIP(const char* pDomain)
{
struct hostent* h = gethostbyname(pDomain);
if( h != NULL )
{
unsigned char* p = (unsigned char *)(h->h_addr_list)[0];
if( p != NULL )
{
char ip[16] = {0};
sprintf(ip, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
return ip;
}
}
return "";
}
/**
* calss : CCInetAddress
* author : Jason lee
* email : jason.lee.c@foxmail.com
* descpt : address define
*/
class CCInetAddress : public sockaddr_in
{
public:
CCInetAddress();
CCInetAddress(const char* ip, unsigned short port);
CCInetAddress(const struct sockaddr* addr);
virtual ~CCInetAddress(void);
public:
operator struct sockaddr*();
operator const struct sockaddr*() const;
const char* getHostAddress() const;
const char* getIp() const;
unsigned short getPort() const;
void setIp(const char* ip);
void setIp(unsigned int ip);
void setPort(unsigned short port);
void setHost(const char* name);
public:
int getLength();
};
NS_CC_END
#endif //__CCNET_INETADDRESS_H__
CCInetAddress.cpp
#include "CCInetAddress.h"
#if( CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 )
#pragma comment(lib, "Ws2_32.lib")
#endif
NS_CC_BEGIN
CCInetAddress::CCInetAddress()
{
#if( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
sin_len = sizeof(struct sockaddr_in);
sin_family = AF_INET;
sin_addr.s_addr = INADDR_ANY;
sin_port = 0;
memset(sin_zero, 0, 8);
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 )
sin_family = AF_INET;
sin_addr.s_addr = INADDR_ANY;
sin_port = 0;
memset(sin_zero, 0, 8);
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
sin_family = AF_INET;
sin_addr.s_addr = INADDR_ANY;
sin_port = 0;
memset(sin_zero, 0, 8);
#endif
}
CCInetAddress::CCInetAddress(const char* ip, unsigned short port)
{
sin_family = AF_INET;
sin_addr.s_addr = inet_addr(ip);
sin_port = htons(port);
memset(sin_zero, 0, 8);
}
CCInetAddress::CCInetAddress(const struct sockaddr * addr)
{
memcpy(&this->sin_family, addr, sizeof(struct sockaddr));
}
CCInetAddress::~CCInetAddress(void)
{
}
CCInetAddress::operator struct sockaddr*()
{
#if( CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 )
return (struct sockaddr *)(&this->sin_family);
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
return (struct sockaddr *)(&this->sin_family);
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
return (struct sockaddr *)(&this->sin_len);
#endif
}
CCInetAddress::operator const struct sockaddr*() const
{
#if( CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 )
return (const struct sockaddr *)(&this->sin_family);
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
return (const struct sockaddr *)(&this->sin_family);
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
return (const struct sockaddr *)(&this->sin_len);
#endif
}
const char* CCInetAddress::getHostAddress() const
{
static char addr[64];
#if( CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 )
sprintf_s(addr, 64, "%s:%u", inet_ntoa(sin_addr), getPort());
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID )
snprintf(addr, 64, "%s:%u", inet_ntoa(sin_addr), getPort());
#endif
#if( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
snprintf(addr, 64, "%s:%u", inet_ntoa(sin_addr), getPort());
#endif
return addr;
}
const char* CCInetAddress::getIp() const
{
return inet_ntoa(sin_addr);
}
unsigned short CCInetAddress::getPort() const
{
return ntohs(sin_port);
}
void CCInetAddress::setIp(const char* ip)
{
sin_addr.s_addr = inet_addr(ip);
}
void CCInetAddress::setIp(unsigned int ip)
{
sin_addr.s_addr = ip;
}
void CCInetAddress::setPort(unsigned short port)
{
sin_port = htons(port);
}
void CCInetAddress::setHost(const char* name)
{
hostent* h = gethostbyname(name);
if( h != NULL )
{
sin_addr.s_addr = *((u_long *)h->h_addr_list[0]);
}
}
int CCInetAddress::getLength()
{
return sizeof(sockaddr_in);
}
NS_CC_END
我的配置文件
cNet.ini
[cNet]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cNet
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = cNet
# the native namespace in which this module locates, this parameter is used for avoid conflict of the same class name in different modules, as "cocos2d::Label" <-> "cocos2d::ui::Label".
cpp_namespace =
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.9/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/%(clang_include)s
clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/external/sources
cocos_flags = -DANDROID
cxxgenerator_headers =
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
# what headers to parse
headers = %(cocosdir)s/cNet/CCInetAddress.h
replace_headers =
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = CCInetAddress
classes_need_extend =
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip =
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =
# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes =
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp =
本人CC新人,C++小白请大神们诊断,谢谢。