diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java
index 824e34a248d20e5798b67fb390577bc528c8fc64..2148bacc3b634dd3ddeab1d32df7ff12128e914e 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java
@@ -39,18 +39,11 @@ public class JNI_C implements CRFFI {
          */
         @Override
         @TruffleBoundary
-        public void execute(NativeCallInfo nativeCallInfo, Object[] args) {
+        public void execute(NativeCallInfo nativeCallInfo, Object[] args, boolean hasStrings) {
             synchronized (JNI_C.class) {
                 if (traceEnabled()) {
                     traceDownCall(nativeCallInfo.name, args);
                 }
-                boolean hasStrings = false;
-                for (int i = 0; i < args.length; i++) {
-                    if (args[i] instanceof byte[][]) {
-                        hasStrings = true;
-                        break;
-                    }
-                }
                 c(nativeCallInfo.address.asAddress(), args, hasStrings);
             }
         }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java
index 8ec43a990d610eb904a10c6f047c7e64726fc7f3..42e9037d12ae7a16eef962a1b231039054463353 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java
@@ -40,7 +40,7 @@ class TruffleLLVM_C implements CRFFI {
         private int numArgs;
 
         @Override
-        public synchronized void execute(NativeCallInfo nativeCallInfo, Object[] args) {
+        public synchronized void execute(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings) {
             TruffleLLVM_DLL.ensureParsed(nativeCallInfo);
             Object[] wargs = wrap(args);
             try {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java
index 939549b4f6d2f1dcf720c28507d84b20ae7ba30c..56ec23201e6206321ac023bbac3a27071ac0d851 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java
@@ -42,7 +42,7 @@ public class TruffleNFI_C implements CRFFI {
         @Child private Node bindNode = Message.createInvoke(1).createNode();
 
         @Specialization(guards = "args.length == 0")
-        protected void invokeCall0(NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args,
+        protected void invokeCall0(NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -56,7 +56,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 1")
-        protected void invokeCall1(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall1(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -71,7 +71,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 2")
-        protected void invokeCall2(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall2(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -86,7 +86,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 3")
-        protected void invokeCall3(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall3(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -101,7 +101,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 4")
-        protected void invokeCall4(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall4(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -116,7 +116,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Fallback
-        protected void invokeCallN(@SuppressWarnings("unused") NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args) {
+        protected void invokeCallN(@SuppressWarnings("unused") NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") boolean hasStrings) {
             synchronized (TruffleNFI_Call.class) {
                 throw RInternalError.unimplemented(".C (too many args)");
             }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
index b1c2b49fce9cb8eec2aef4f52bda0ea189a11aa0..9665e68e3081cbfa66c2f13dd2b8212db3deb626 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
@@ -85,6 +85,7 @@ public class FortranAndCFunctions {
             Object[] array = args.getArguments();
             int[] argTypes = new int[array.length];
             Object[] nativeArgs = new Object[array.length];
+            boolean hasStrings = false;
             for (int i = 0; i < array.length; i++) {
                 Object arg = array[i];
                 if (arg instanceof RAbstractDoubleVector) {
@@ -104,10 +105,12 @@ public class FortranAndCFunctions {
                     }
                     nativeArgs[i] = checkNAs(node, i + 1, dataAsInt);
                 } else if (arg instanceof RAbstractStringVector) {
+                    hasStrings = true;
                     argTypes[i] = VECTOR_STRING;
                     checkNAs(node, i + 1, (RAbstractStringVector) arg);
                     nativeArgs[i] = encodeStrings((RAbstractStringVector) arg);
                 } else if (arg instanceof String) {
+                    hasStrings = true;
                     argTypes[i] = SCALAR_STRING;
                     checkNAs(node, i + 1, RString.valueOf((String) arg));
                     nativeArgs[i] = new byte[][]{encodeString((String) arg)};
@@ -124,7 +127,7 @@ public class FortranAndCFunctions {
                     throw node.error(RError.Message.UNIMPLEMENTED_ARG_TYPE, i + 1);
                 }
             }
-            invokeCNode.execute(nativeCallInfo, nativeArgs);
+            invokeCNode.execute(nativeCallInfo, nativeArgs, hasStrings);
             // we have to assume that the native method updated everything
             RStringVector listNames = validateArgNames(array.length, args.getSignature());
             Object[] results = new Object[array.length];
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
index f5b547d987b795fa82d8e76b5e25d0ddae68f933..c914be958fcfedee11a6b50ff5a2e80c540e0d2f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
@@ -33,8 +33,12 @@ public interface CRFFI {
          * Invoke the native method identified by {@code symbolInfo} passing it the arguments in
          * {@code args}. The values in {@code args} should be native types,e.g., {@code double[]}
          * not {@code RDoubleVector}. Strings are already converted to 2-dimensional byte arrays.
+         *
+         * @param hasStrings if {@code true}, then the {@code args} array may contain one or more
+         *            values of type {@code byte[][]}, which represent arrays of strings in ASCII
+         *            encoding.
          */
-        public abstract void execute(NativeCallInfo nativeCallInfo, Object[] args);
+        public abstract void execute(NativeCallInfo nativeCallInfo, Object[] args, boolean hasStrings);
     }
 
     InvokeCNode createInvokeCNode();