问题
I am developing a desktop Air application that uses an Air Native Extension (ANE). The native part of the ANE is composed only by a DLL written partially in C and partially in C++. The app was compiled with Visual Studio 2010 and requires the MSVCR100.DLL and the MSVCP100.DLL to be on the same directory as the application's exe file.
The app and DLL work great on many computers but on clean Windows 7 SP1 computers, part of its code makes the DLL crash.
I've narrowed down the conflicting code to the following:
// Addresses.
String^ defaultGateway = "Not Found";
String^ interfaceIPAddress = "Not Found";
String^ interfaceMask = "Not Found";
array<NetworkInterface^>^nics = NetworkInterface::GetAllNetworkInterfaces();
if (nics != nullptr || nics->Length > 0)
{
System::Collections::IEnumerator^ myEnum4 = nics->GetEnumerator();
while (myEnum4->MoveNext())
{
NetworkInterface^ adapter = safe_cast<NetworkInterface ^>(myEnum4->Current);
IPInterfaceProperties^ properties = adapter->GetIPProperties();
GatewayIPAddressInformationCollection^ gateways = properties->GatewayAddresses;
for each (GatewayIPAddressInformation^ gateway in gateways)
{
if (gateway->Address->AddressFamily == AddressFamily::InterNetwork)
{
defaultGateway = gateway->Address->ToString();
for each (UnicastIPAddressInformation^ unicastIPAddressInformation in properties->UnicastAddresses)
{
if (unicastIPAddressInformation->Address->AddressFamily == AddressFamily::InterNetwork)
{
interfaceIPAddress = unicastIPAddressInformation->Address->ToString();
interfaceMask = unicastIPAddressInformation->IPv4Mask->ToString();
}
}
}
}
}
}
Just to give you more context, I'll copy the entire function were that code is:
FREObject MainInterfaceInfo(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])
{
// Addresses.
String^ defaultGateway = "Not Found";
String^ interfaceIPAddress = "Not Found";
String^ interfaceMask = "Not Found";
array<NetworkInterface^>^nics = NetworkInterface::GetAllNetworkInterfaces();
if (nics != nullptr || nics->Length > 0)
{
System::Collections::IEnumerator^ myEnum4 = nics->GetEnumerator();
while (myEnum4->MoveNext())
{
NetworkInterface^ adapter = safe_cast<NetworkInterface ^>(myEnum4->Current);
IPInterfaceProperties^ properties = adapter->GetIPProperties();
GatewayIPAddressInformationCollection^ gateways = properties->GatewayAddresses;
for each (GatewayIPAddressInformation^ gateway in gateways)
{
if (gateway->Address->AddressFamily == AddressFamily::InterNetwork)
{
defaultGateway = gateway->Address->ToString();
for each (UnicastIPAddressInformation^ unicastIPAddressInformation in properties->UnicastAddresses)
{
if (unicastIPAddressInformation->Address->AddressFamily == AddressFamily::InterNetwork)
{
interfaceIPAddress = unicastIPAddressInformation->Address->ToString();
interfaceMask = unicastIPAddressInformation->IPv4Mask->ToString();
}
}
}
}
}
}
String^ result = interfaceIPAddress + ";" + interfaceMask + ";" + defaultGateway;
// Converting the response to const uint8_t *
msclr::interop::marshal_context oMarshalContext;
const char* charResponse = oMarshalContext.marshal_as<const char*>(result);
const uint8_t * resultNativeCharArray = (const uint8_t *)charResponse;
uint32_t resultNativeCharArrayLength = 0;
while (true) {
if (NULL == resultNativeCharArray[resultNativeCharArrayLength]) {
break;
}
else {
resultNativeCharArrayLength++;
}
}
FREObject functionResult;
FRENewObjectFromUTF8(resultNativeCharArrayLength, resultNativeCharArray, &functionResult);
return functionResult;
}
I'm a noob on C and C++ because I only saw it a couple of times 10 years ago so I have no clue about what exactly is making the DLL crash. Can someone tell? Any advice will be more than appreciated.
Editted
I came to realize that the same narrowed code makes the app require the MSVCR100.DLL and the MSVCP100.DLL. If I remove that portion of code, the app can run without them.
回答1:
MSVCP100.DLL contains the standard C++ Library; MSVCR100.DLL is the C runtime. It's probably something like the safe_cast
call that's introducing the dependency. More details about the runtime libraries are here.
I'd suggest using the official redistributable package to deploy the Visual C++ runtimes DLLs instead of deploying them into your app's directory yourself. See Redistributing Visual C++ Files for details... the walkthrough links in there will be helpful to you. That's the sure-fire way to be sure that the target system has all the dependencies you'll need. Your older (non-clean) Win7 systems probably had some other app or Windows Update install that redistributable for you, which is why your code is working there.
回答2:
Actually, the line of code that was messing everything up was:
interfaceMask = unicastIPAddressInformation->IPv4Mask->ToString();
If that line was deleted, the DLL would run without a problem.
The issue occurred because one of the inactive network interfaces of the system reported '0.0.0.0' on gateway->Address->ToString()
. So when trying to unicastIPAddressInformation->IPv4Mask->ToString()
the DLL would crash.
To solve the issue I just added an if (adapter->OperationalStatus == OperationalStatus::Up)
at the beggining and everything worked great afterwards. The resulting code is as follows:
while (myEnum4->MoveNext())
{
NetworkInterface^ adapter = safe_cast<NetworkInterface ^>(myEnum4->Current);
IPInterfaceProperties^ properties = adapter->GetIPProperties();
if (adapter->OperationalStatus == OperationalStatus::Up)
{
GatewayIPAddressInformationCollection^ gateways = properties->GatewayAddresses;
for each (GatewayIPAddressInformation^ gateway in gateways)
{
if (gateway->Address->AddressFamily == AddressFamily::InterNetwork)
{
defaultGateway = gateway->Address->ToString();
for each (UnicastIPAddressInformation^ unicastIPAddressInformation in properties->UnicastAddresses)
{
if (unicastIPAddressInformation->Address->AddressFamily == AddressFamily::InterNetwork)
{
interfaceIPAddress = unicastIPAddressInformation->Address->ToString();
interfaceMask = unicastIPAddressInformation->IPv4Mask->ToString();
}
}
}
}
}
}
来源:https://stackoverflow.com/questions/33941270/section-of-the-code-of-our-c-dll-crashes-wen-ran-on-a-windows-7-sp1