现在的位置: 首页 > 综合 > 正文

Migrating from Internal Linkage to Frozen Linkage

2013年10月22日 ⁄ 综合 ⁄ 共 5733字 ⁄ 字号 评论关闭

Table of contents
  1. 1. Strings
  2. 2. Missing Headers
  3. 3. Utility Classes
  4. 4. nsCRT

Migrating from Internal Linkage to Frozen Linkage

Table of contents
  1. 1. Strings
  2. 2. Missing Headers
  3. 3. Utility Classes
  4. 4. nsCRT

Extension code using internal linkage will need to migrate to use frozen linkage because internal linkage will not be available in Firefox 3. This document is a guide to common code patterns that may need to change to work with frozen linkage.

Strings

The most obvious change required by frozen linkage is using the frozen string API.

- #include "nsAString.h"
- #include "nsString.h"
- #include "nsReadableUtils.h"
- #include "nsEscape.h"
+ #include "nsStringAPI.h"

On Windows, if you see the following error, you are including a header you shouldn't be:

nsStringFwd.h(60) : fatal error C1001: INTERNAL COMPILER ERROR

To debug this error, make in the failing directory, adding the /showIncludes directive to figure out what is being included incorrectly:

make -C directory/that/failed OS_CPPFLAGS=-showIncludes

The frozen string API is similar but not identical to the nonfrozen string API. The frozen string API does not have (or need) nsXPIDLString:

- nsXPIDLString value;
+ nsString value;
  ptr->GetterMethod(getter_Copies(value));
- const PRUnichar *strvalue = value;
+ // nsString doesn't cast directly to PRUnichar*, use .get()
+ const PRUnichar *strvalue = value.get();

The frozen string API doesn't accept a length for .Truncate(). Use .SetLength() instead:

  nsString myString = someString;
- myString.Truncate(4);
+ myString.SetLength(4);

The frozen string API doesn't support the iterator or const_iterator classes, but you can use pointers the same way:

  nsString myString = someString;
- nsString::const_iterator begin, end;
- myString.BeginReading(begin); myString.EndReading(end);
+ const PRUnichar *begin, *end;
+ myString.BeginReading(&begin, &end);

The frozen string API uses comparator functions instead of a virtual comparator class. unicharutils has been modified to provide a frozen-linkage comparator:

  nsString myString = someString;
- if (myString.Equals(otherString, nsCaseInsensitiveStringComparator()))
+ if (myString.Equals(otherString, CaseInsensitiveCompare))
    return NS_OK; // woot, we're equal in all things but case
When using unicharutils from frozen-linkage code, link against the unicharutil_external_s static library.

The frozen string API doesn't implement the Left(), Mid(), or Right() signatures. Use StringHead(), Substring(), and StringTail() instead:

  nsString buffer = someString;
- nsCAutoString prefix;
- buffer.Left(prefix, 4);
+ const nsDependentSubstring prefix = StringHead(buffer, 4);

The frozen string API doesn't use nsSubstringTuple objects and maintains all strings in a contiguous buffer. This means that the + operator is not implemented, nor are the PromiseFlatString functions or classes around any more. Use += or Append() instead of using +, and use nsString or nsCString instead of PromiseFlatString:

  nsString firstString = someString;
  nsString secondString = someOtherString;
- nsString comboString = firstString + secondString; + nsString comboString = firstString; + comboString += secondString; // or: comboString.Append(secondString);
- nsresult rv = SomeFunc(PromiseFlatString(comboString)); + nsresult rv = SomeFunc(comboString);

Removing the nsReadableUtils.h from the headers list also means that we would not have access to AppendUTF16toUTF8 kind of functions. All these functions are now available via the new String API

 - AppendUTF16toUTF8(srcString, destString);
 + destString.Append(NS_ConvertUTF16toUTF8(srcString));

Missing Headers

Some headers are included from IDL files only when MOZILLA_INTERNAL_API is defined (actually, they shouldn't be there at all).

For errors about undeclared do_CreateInstance:

#include "nsComponentManagerUtils.h"

For errors about undeclared do_GetService:

#include "nsServiceManagerUtils.h"

For errors about undeclared NS_GetSpecialDirectory:

#include "nsDirectoryServiceUtils.h"

Utility Classes

Some utility classes could previously be created with NS_New* utility functions. These classes must now be created using XPCOM:

  // nsISupportsArray is bad! Don't use it in new code. Use nsIArray instead. (See XPCOM:Arrays.)
  nsCOMPtr<nsISupportsArray> array;
- rv = NS_NewISupportsArray(getter_AddRefs(array));
+ array = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
- nsCOMPtr<nsIInputStream> rawStream;
- rv = NS_NewByteInputStream(getter_AddRefs(rawStream),
-                            (const char*)data, length);
+ nsCOMPtr<nsIStringInputStream> rawStream =
+   do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = rawStream->SetData((const char*)data, length);
  NS_ENSURE_SUCCESS(rv, rv);

nsIStringInputStream is not frozen (and thus, not available in the Gecko SDK as currently published). In order to use this interface in your code, you will need to get the IDL files from the source (via CVS, from a tarball, or using LXR).

The following functions, however, are implemented in the glue library and can be used from frozen-linkage code:

  • NS_NewArrayEnumerator (excluding deprecated nsISupportsArray version)
  • NS_NewEmptyEnumerator
  • NS_NewUnionEnumerator

nsCRT

nsCRT is not available to frozen-linkage code.

- #include "nsCRT.h"
+ #include <string.h>

  const char *str = "Foo";
- PRUint32 len = nsCRT::strlen(str);
+ PRUint32 len = strlen(str);

- #include "nsCRT.h"
+ #include "nsCRTGlue.h"

  const PRUnichar str[] = {'F','o','o','/0'};
- PRUint32 len = nsCRT::strlen(str);
+ PRUint32 len = NS_strlen(str);

- #include "nsCRT.h"
+ #include "nsMemory.h"
+ #include "nsCRTGlue.h"

  PRUnichar* anotherstr = (PRUnichar*) NS_Alloc(100 * sizeof(PRUnichar));
- PRUnichar *str = nsCRT::strdup(anotherstr);
- nsCRT::free(str);
+ PRUnichar *str = NS_strdup(anotherstr);
+ NS_Free(str);

Page last modified 15:23, 28 Aug 2007 by Benjamin Smedberg

Files (0)

 

 
 

抱歉!评论已关闭.